elm-pages 2.1.11 → 3.0.0-beta.0

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 (136) hide show
  1. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmi +0 -0
  2. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmo +0 -0
  3. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmi +0 -0
  4. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmo +0 -0
  5. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolationsTest.elmi +0 -0
  6. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolationsTest.elmo +0 -0
  7. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Reporter.elmi +0 -0
  8. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Reporter.elmo +0 -0
  9. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Runner.elmi +0 -0
  10. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Runner.elmo +0 -0
  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/elm-stuff/0.19.1/i.dat +0 -0
  13. package/generator/{template/public/style.css → review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/lock} +0 -0
  14. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  15. package/generator/review/elm-stuff/tests-0.19.1/elm.json +1 -0
  16. package/generator/review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +6795 -0
  17. package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +27617 -0
  18. package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +110 -0
  19. package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +187 -0
  20. package/generator/review/elm-stuff/tests-0.19.1/js/package.json +1 -0
  21. package/generator/review/elm-stuff/tests-0.19.1/src/Reporter.elm +26 -0
  22. package/generator/review/elm-stuff/tests-0.19.1/src/Runner.elm +62 -0
  23. package/generator/review/elm.json +13 -4
  24. package/{src → generator/review/src}/Pages/Review/NoContractViolations.elm +148 -148
  25. package/generator/review/tests/Pages/Review/NoContractViolationsTest.elm +331 -0
  26. package/generator/src/RouteBuilder.elm +420 -0
  27. package/generator/src/SharedTemplate.elm +4 -5
  28. package/generator/src/SiteConfig.elm +3 -9
  29. package/generator/src/build.js +308 -95
  30. package/generator/src/cli.js +103 -8
  31. package/generator/src/codegen.js +192 -35
  32. package/generator/src/compile-elm.js +183 -31
  33. package/generator/src/dev-server.js +353 -96
  34. package/generator/src/elm-application.json +3 -1
  35. package/generator/src/elm-codegen.js +34 -0
  36. package/generator/src/elm-file-constants.js +2 -0
  37. package/generator/src/error-formatter.js +20 -1
  38. package/generator/src/generate-template-module-connector.js +120 -924
  39. package/generator/src/hello.ts +5 -0
  40. package/generator/src/pre-render-html.js +58 -104
  41. package/generator/src/render-worker.js +27 -13
  42. package/generator/src/render.js +252 -197
  43. package/generator/src/request-cache-fs.js +18 -0
  44. package/generator/src/request-cache.js +128 -56
  45. package/generator/src/rewrite-client-elm-json.js +49 -0
  46. package/generator/src/route-codegen-helpers.js +62 -1
  47. package/generator/static-code/dev-style.css +22 -0
  48. package/generator/static-code/elm-pages.js +43 -39
  49. package/generator/static-code/hmr.js +98 -88
  50. package/generator/template/app/Api.elm +25 -0
  51. package/generator/template/app/ErrorPage.elm +38 -0
  52. package/generator/template/app/Route/Index.elm +87 -0
  53. package/generator/template/{src → app}/Shared.elm +34 -13
  54. package/generator/template/app/Site.elm +19 -0
  55. package/generator/template/{src → app}/View.elm +0 -0
  56. package/generator/template/elm-pages.config.mjs +5 -0
  57. package/generator/template/elm.json +1 -0
  58. package/generator/template/{public/index.js → index.ts} +7 -3
  59. package/generator/template/package.json +4 -4
  60. package/generator/template/public/favicon.ico +0 -0
  61. package/generator/template/public/images/icon-png.png +0 -0
  62. package/generator/template/src/.gitkeep +0 -0
  63. package/generator/template/style.css +4 -0
  64. package/package.json +30 -23
  65. package/src/ApiRoute.elm +176 -43
  66. package/src/BuildError.elm +10 -1
  67. package/src/CookieParser.elm +84 -0
  68. package/src/DataSource/Env.elm +38 -0
  69. package/src/DataSource/File.elm +27 -16
  70. package/src/DataSource/Glob.elm +126 -80
  71. package/src/DataSource/Http.elm +283 -304
  72. package/src/DataSource/Internal/Glob.elm +5 -21
  73. package/src/DataSource/Internal/Request.elm +25 -0
  74. package/src/DataSource/Port.elm +17 -14
  75. package/src/DataSource.elm +55 -318
  76. package/src/Form/Field.elm +717 -0
  77. package/src/Form/FieldStatus.elm +36 -0
  78. package/src/Form/FieldView.elm +417 -0
  79. package/src/Form/FormData.elm +22 -0
  80. package/src/Form/Validation.elm +391 -0
  81. package/src/Form/Value.elm +118 -0
  82. package/src/Form.elm +1683 -0
  83. package/src/FormData.elm +58 -0
  84. package/src/FormDecoder.elm +102 -0
  85. package/src/Head/Seo.elm +12 -4
  86. package/src/Head.elm +12 -2
  87. package/src/HtmlPrinter.elm +1 -1
  88. package/src/Internal/ApiRoute.elm +17 -4
  89. package/src/Internal/Request.elm +7 -0
  90. package/src/PageServerResponse.elm +68 -0
  91. package/src/Pages/ContentCache.elm +1 -229
  92. package/src/Pages/Fetcher.elm +58 -0
  93. package/src/Pages/FormState.elm +256 -0
  94. package/src/Pages/Generate.elm +800 -0
  95. package/src/Pages/Internal/Form.elm +17 -0
  96. package/src/Pages/Internal/NotFoundReason.elm +3 -55
  97. package/src/Pages/Internal/Platform/Cli.elm +777 -579
  98. package/src/Pages/Internal/Platform/Effect.elm +5 -5
  99. package/src/Pages/Internal/Platform/StaticResponses.elm +178 -394
  100. package/src/Pages/Internal/Platform/ToJsPayload.elm +24 -23
  101. package/src/Pages/Internal/Platform.elm +1244 -504
  102. package/src/Pages/Internal/ResponseSketch.elm +19 -0
  103. package/src/Pages/Internal/RoutePattern.elm +596 -45
  104. package/src/Pages/Manifest.elm +26 -0
  105. package/src/Pages/Msg.elm +79 -0
  106. package/src/Pages/ProgramConfig.elm +67 -14
  107. package/src/Pages/SiteConfig.elm +3 -6
  108. package/src/Pages/StaticHttp/Request.elm +4 -2
  109. package/src/Pages/StaticHttpRequest.elm +50 -215
  110. package/src/Pages/Transition.elm +70 -0
  111. package/src/Path.elm +1 -0
  112. package/src/Pattern.elm +98 -0
  113. package/src/RenderRequest.elm +2 -2
  114. package/src/RequestsAndPending.elm +111 -9
  115. package/src/Server/Request.elm +1253 -0
  116. package/src/Server/Response.elm +292 -0
  117. package/src/Server/Session.elm +316 -0
  118. package/src/Server/SetCookie.elm +169 -0
  119. package/src/TerminalText.elm +1 -1
  120. package/src/Test/Html/Internal/ElmHtml/Markdown.elm +0 -1
  121. package/src/Test/Html/Internal/ElmHtml/ToString.elm +1 -1
  122. package/generator/src/Page.elm +0 -359
  123. package/generator/src/codegen-template-module.js +0 -183
  124. package/generator/src/elm-pages-js-minified.js +0 -1
  125. package/generator/template/src/Api.elm +0 -14
  126. package/generator/template/src/Page/Index.elm +0 -69
  127. package/generator/template/src/Site.elm +0 -41
  128. package/src/DataSource/ServerRequest.elm +0 -60
  129. package/src/Internal/OptimizedDecoder.elm +0 -18
  130. package/src/KeepOrDiscard.elm +0 -6
  131. package/src/OptimizedDecoder/Pipeline.elm +0 -335
  132. package/src/OptimizedDecoder.elm +0 -818
  133. package/src/Pages/Internal/ApplicationType.elm +0 -6
  134. package/src/Pages/Secrets.elm +0 -83
  135. package/src/Secrets.elm +0 -111
  136. package/src/SecretsDict.elm +0 -45
@@ -1,6 +1,5 @@
1
1
  const path = require("path");
2
- const undici = require("undici");
3
- const fs = require("fs");
2
+ const fetch = require("node-fetch");
4
3
  const objectHash = require("object-hash");
5
4
  const kleur = require("kleur");
6
5
 
@@ -17,61 +16,76 @@ function requestToString(request) {
17
16
  /**
18
17
  * @param {Object} request
19
18
  */
20
- function fullPath(request) {
21
- return path.join(
22
- process.cwd(),
23
- ".elm-pages",
24
- "http-response-cache",
25
- requestToString(request)
26
- );
19
+ function fullPath(portsHash, request, hasFsAccess) {
20
+ const requestWithPortHash =
21
+ request.url === "elm-pages-internal://port"
22
+ ? { portsHash, ...request }
23
+ : request;
24
+ if (hasFsAccess) {
25
+ return path.join(
26
+ process.cwd(),
27
+ ".elm-pages",
28
+ "http-response-cache",
29
+ requestToString(requestWithPortHash)
30
+ );
31
+ } else {
32
+ return path.join("/", requestToString(requestWithPortHash));
33
+ }
27
34
  }
28
35
 
29
36
  /**
30
37
  * @param {string} mode
31
- * @param {{url: string; headers: {[x: string]: string}; method: string; body: Body } } rawRequest
38
+ * @param {{url: string;headers: {[x: string]: string;};method: string;body: Body;}} rawRequest
32
39
  * @returns {Promise<string>}
40
+ * @param {string} portsFile
41
+ * @param {boolean} hasFsAccess
33
42
  */
34
- function lookupOrPerform(mode, rawRequest) {
43
+ function lookupOrPerform(portsFile, mode, rawRequest, hasFsAccess, useCache) {
44
+ const { fs } = require("./request-cache-fs.js")(hasFsAccess);
35
45
  return new Promise(async (resolve, reject) => {
36
46
  const request = toRequest(rawRequest);
37
- const responsePath = fullPath(request);
47
+ const portsHash = (portsFile && portsFile.match(/-([^-]+)\.js$/)[1]) || "";
48
+ const responsePath = fullPath(portsHash, request, hasFsAccess);
38
49
 
39
- if (fs.existsSync(responsePath)) {
50
+ // TODO check cache expiration time and delete and go to else if expired
51
+ if (useCache && (await checkFileExists(fs, responsePath))) {
40
52
  // console.log("Skipping request, found file.");
41
53
  resolve(responsePath);
42
54
  } else {
43
55
  let portDataSource = {};
44
- let portDataSourceFound = false;
56
+ let portDataSourceImportError = null;
45
57
  try {
46
- portDataSource = requireUncached(
47
- mode,
48
- path.join(process.cwd(), "port-data-source.js")
49
- );
50
- portDataSourceFound = true;
51
- } catch (e) {}
58
+ if (portsFile === undefined) {
59
+ throw "missing";
60
+ }
61
+ const portDataSourcePath = path.resolve(portsFile);
62
+ // On Windows, we need cannot use paths directly and instead must use a file:// URL.
63
+ // portDataSource = await require(url.pathToFileURL(portDataSourcePath).href);
64
+ portDataSource = require(portDataSourcePath);
65
+ } catch (e) {
66
+ portDataSourceImportError = e;
67
+ }
52
68
 
53
- if (request.url.startsWith("port://")) {
69
+ if (request.url === "elm-pages-internal://port") {
54
70
  try {
55
- const portName = request.url.replace(/^port:\/\//, "");
56
- // console.time(JSON.stringify(request.url));
71
+ const { input, portName } = rawRequest.body.args[0];
72
+
57
73
  if (!portDataSource[portName]) {
58
- if (portDataSourceFound) {
59
- throw `DataSource.Port.send "${portName}" is not defined. Be sure to export a function with that name from port-data-source.js`;
74
+ if (portDataSourceImportError === null) {
75
+ throw `DataSource.Port.send "${portName}" was called, but I couldn't find a function with that name in the port definitions file. Is it exported correctly?`;
76
+ } else if (portDataSourceImportError === "missing") {
77
+ throw `DataSource.Port.send "${portName}" was called, but I couldn't find the port definitions file. Be sure to create a 'port-data-source.ts' or 'port-data-source.js' file and maybe restart the dev server.`;
60
78
  } else {
61
- throw `DataSource.Port.send "${portName}" was called, but I couldn't find the port definitions file 'port-data-source.js'.`;
79
+ throw `DataSource.Port.send "${portName}" was called, but I couldn't import the port definitions file, because of this exception: \`${portDataSourceImportError}\` Are there syntax errors or expections thrown during import?`;
62
80
  }
63
81
  } else if (typeof portDataSource[portName] !== "function") {
64
- throw `DataSource.Port.send "${portName}" is not a function. Be sure to export a function with that name from port-data-source.js`;
82
+ throw `DataSource.Port.send "${portName}" was called, but it is not a function. Be sure to export a function with that name from port-data-source.js`;
65
83
  }
66
84
  await fs.promises.writeFile(
67
85
  responsePath,
68
- JSON.stringify(
69
- await portDataSource[portName](rawRequest.body.args[0])
70
- )
86
+ JSON.stringify(jsonResponse(await portDataSource[portName](input)))
71
87
  );
72
88
  resolve(responsePath);
73
-
74
- // console.timeEnd(JSON.stringify(requestToPerform.masked));
75
89
  } catch (error) {
76
90
  console.trace(error);
77
91
  reject({
@@ -80,38 +94,81 @@ function lookupOrPerform(mode, rawRequest) {
80
94
  });
81
95
  }
82
96
  } else {
83
- undici
84
- .stream(
85
- request.url,
86
- {
87
- method: request.method,
88
- body: request.body,
89
- headers: {
90
- "User-Agent": "request",
91
- ...request.headers,
92
- },
97
+ try {
98
+ console.time(`fetch ${request.url}`);
99
+ const response = await fetch(request.url, {
100
+ method: request.method,
101
+ body: request.body,
102
+ headers: {
103
+ "User-Agent": "request",
104
+ ...request.headers,
93
105
  },
94
- (response) => {
95
- const writeStream = fs.createWriteStream(responsePath);
96
- writeStream.on("finish", async () => {
97
- resolve(responsePath);
98
- });
106
+ });
99
107
 
100
- return writeStream;
101
- }
102
- )
103
- .catch((error) => {
104
- let errorMessage = error.toString();
105
- if (error.code === "ENOTFOUND") {
106
- errorMessage = `Could not reach URL.`;
108
+ console.timeEnd(`fetch ${request.url}`);
109
+ const expectString = request.headers["elm-pages-internal"];
110
+
111
+ if (response.ok || expectString === "ExpectResponse") {
112
+ let body;
113
+ let bodyKind;
114
+ if (expectString === "ExpectJson") {
115
+ body = await response.json();
116
+ bodyKind = "json";
117
+ } else if (
118
+ expectString === "ExpectBytes" ||
119
+ expectString === "ExpectBytesResponse"
120
+ ) {
121
+ bodyKind = "bytes";
122
+ const arrayBuffer = await response.arrayBuffer();
123
+ body = Buffer.from(arrayBuffer).toString("base64");
124
+ } else if (expectString === "ExpectWhatever") {
125
+ bodyKind = "whatever";
126
+ body = null;
127
+ } else if (
128
+ expectString === "ExpectResponse" ||
129
+ expectString === "ExpectString"
130
+ ) {
131
+ bodyKind = "string";
132
+ body = await response.text();
133
+ } else {
134
+ throw `Unexpected expectString ${expectString}`;
107
135
  }
136
+
137
+ await fs.promises.writeFile(
138
+ responsePath,
139
+ JSON.stringify({
140
+ headers: Object.fromEntries(response.headers.entries()),
141
+ statusCode: response.status,
142
+ body: body,
143
+ bodyKind,
144
+ url: response.url,
145
+ statusText: response.statusText,
146
+ })
147
+ );
148
+
149
+ resolve(responsePath);
150
+ } else {
151
+ console.log("@@@ request-cache1 bad HTTP response");
108
152
  reject({
109
153
  title: "DataSource.Http Error",
110
154
  message: `${kleur
111
155
  .yellow()
112
- .underline(request.url)} ${errorMessage}`,
156
+ .underline(request.url)} Bad HTTP response ${response.status} ${
157
+ response.statusText
158
+ }
159
+ `,
113
160
  });
161
+ }
162
+ } catch (error) {
163
+ console.trace("@@@ request-cache2 HTTP error", error);
164
+ reject({
165
+ title: "DataSource.Http Error",
166
+ message: `${kleur
167
+ .yellow()
168
+ .underline(request.url)} ${error.toString()}
169
+ `,
114
170
  });
171
+ }
115
172
  }
116
173
  }
117
174
  });
@@ -131,7 +188,15 @@ function toRequest(elmRequest) {
131
188
  body: toBody(elmRequest.body),
132
189
  };
133
190
  }
134
-
191
+ /**
192
+ * @param {string} file
193
+ */
194
+ function checkFileExists(fs, file) {
195
+ return fs.promises
196
+ .access(file, fs.constants.F_OK)
197
+ .then(() => true)
198
+ .catch(() => false);
199
+ }
135
200
  /**
136
201
  * @param {Body} body
137
202
  */
@@ -177,4 +242,11 @@ function requireUncached(mode, filePath) {
177
242
  return require(filePath);
178
243
  }
179
244
 
245
+ /**
246
+ * @param {unknown} json
247
+ */
248
+ function jsonResponse(json) {
249
+ return { bodyKind: "json", body: json };
250
+ }
251
+
180
252
  module.exports = { lookupOrPerform };
@@ -0,0 +1,49 @@
1
+ const fs = require("fs");
2
+
3
+ module.exports = async function () {
4
+ var elmJson = JSON.parse(
5
+ (await fs.promises.readFile("./elm.json")).toString()
6
+ );
7
+
8
+ // write new elm.json
9
+
10
+ await writeFileIfChanged(
11
+ "./elm-stuff/elm-pages/client/elm.json",
12
+ JSON.stringify(rewriteElmJson(elmJson))
13
+ );
14
+ };
15
+
16
+ function rewriteElmJson(elmJson) {
17
+ // The internal generated file will be at:
18
+ // ./elm-stuff/elm-pages/
19
+ // So, we need to take the existing elmJson and
20
+ // 1. remove existing path that looks at `Pages.elm`
21
+ elmJson["source-directories"] = elmJson["source-directories"].filter(
22
+ (item) => {
23
+ return item != ".elm-pages" && item != "app";
24
+ }
25
+ );
26
+ // 2. prepend ../../../ to remaining
27
+ elmJson["source-directories"] = elmJson["source-directories"].map((item) => {
28
+ return "../../../" + item;
29
+ });
30
+ // 3. add our own secret My.elm module 😈
31
+ elmJson["source-directories"].push(".elm-pages");
32
+ elmJson["source-directories"].push("app");
33
+ return elmJson;
34
+ }
35
+
36
+ async function writeFileIfChanged(filePath, content) {
37
+ if (
38
+ !(await fileExists(filePath)) ||
39
+ (await fs.promises.readFile(filePath, "utf8")) !== content
40
+ ) {
41
+ await fs.promises.writeFile(filePath, content);
42
+ }
43
+ }
44
+ function fileExists(file) {
45
+ return fs.promises
46
+ .access(file, fs.constants.F_OK)
47
+ .then(() => true)
48
+ .catch(() => false);
49
+ }
@@ -177,6 +177,62 @@ function toPathPattern(name) {
177
177
  .join("/")
178
178
  );
179
179
  }
180
+ /**
181
+ * @param {string[]} name
182
+ * @returns {string[]}
183
+ */
184
+ function toPathPatterns(name) {
185
+ const segments = parseRouteParamsWithStatic(name);
186
+
187
+ const lastSegment = segments[segments.length - 1];
188
+ const allButLast = segments.slice(0, segments.length - 1);
189
+ if (lastSegment && lastSegment.kind === "optional") {
190
+ return [
191
+ joinPath(newHelper(allButLast)),
192
+ joinPath(newHelper(allButLast).concat(`:${lastSegment.name}`)),
193
+ ];
194
+ } else {
195
+ return [joinPath(newHelper(segments))];
196
+ }
197
+ }
198
+
199
+ /**
200
+ * @param {string[]} segments
201
+ */
202
+ function joinPath(segments) {
203
+ const joined = segments.join("/");
204
+ if (joined.startsWith("/")) {
205
+ return joined;
206
+ } else {
207
+ return "/" + joined;
208
+ }
209
+ }
210
+
211
+ /**
212
+ * @return {string[]}
213
+ */
214
+ function newHelper(segments) {
215
+ return segments.map((param) => {
216
+ switch (param.kind) {
217
+ case "static": {
218
+ return camelToKebab(param.name);
219
+ }
220
+ case "dynamic": {
221
+ return `:${param.name}`;
222
+ }
223
+ case "optional": {
224
+ return `[:${param.name}]`;
225
+ }
226
+ case "required-splat": {
227
+ return `*`;
228
+ }
229
+ case "optional-splat": {
230
+ return `*`;
231
+ }
232
+ }
233
+ });
234
+ // .join("/");
235
+ }
180
236
 
181
237
  /**
182
238
  * @param {string[]} name
@@ -211,7 +267,11 @@ function toElmPathPattern(name) {
211
267
  .flatMap((param) => {
212
268
  switch (param.kind) {
213
269
  case "static": {
214
- return [`Pages.Internal.RoutePattern.StaticSegment "${camelToKebab(param.name)}"`];
270
+ return [
271
+ `Pages.Internal.RoutePattern.StaticSegment "${camelToKebab(
272
+ param.name
273
+ )}"`,
274
+ ];
215
275
  }
216
276
  case "dynamic": {
217
277
  return [`Pages.Internal.RoutePattern.DynamicSegment "${param.name}"`];
@@ -308,6 +368,7 @@ module.exports = {
308
368
  toFieldName,
309
369
  paramsRecord,
310
370
  toPathPattern,
371
+ toPathPatterns,
311
372
  parseRouteParams,
312
373
  parseRouteParamsWithStatic,
313
374
  toElmPathPattern,
@@ -0,0 +1,22 @@
1
+ @keyframes lds-default {
2
+ 0%,
3
+ 20%,
4
+ 80%,
5
+ 100% {
6
+ transform: scale(1);
7
+ }
8
+ 50% {
9
+ transform: scale(1.5);
10
+ }
11
+ }
12
+ #not-found-reason code {
13
+ color: rgb(226, 0, 124);
14
+ }
15
+ #not-found-reason h1 {
16
+ font-size: 26px;
17
+ font-weight: bold;
18
+ padding-bottom: 15px;
19
+ }
20
+ #not-found-reason a:hover {
21
+ text-decoration: underline;
22
+ }
@@ -1,8 +1,7 @@
1
- import userInit from "/index.js";
2
-
3
- let prefetchedPages = [window.location.pathname];
4
- let initialLocationHash = document.location.hash.replace(/^#/, "");
1
+ import userInit from "/index";
5
2
 
3
+ let prefetchedPages;
4
+ let initialLocationHash;
6
5
  /**
7
6
  * @returns
8
7
  */
@@ -11,15 +10,15 @@ function loadContentAndInitializeApp() {
11
10
  if (!path.endsWith("/")) {
12
11
  path = path + "/";
13
12
  }
14
- const app = Elm.TemplateModulesBeta.init({
13
+ const app = Elm.Main.init({
15
14
  flags: {
16
15
  secrets: null,
17
16
  isPrerendering: false,
18
17
  isDevServer: false,
19
18
  isElmDebugMode: false,
20
- contentJson: JSON.parse(
21
- document.getElementById("__ELM_PAGES_DATA__").innerHTML
22
- ),
19
+ contentJson: {},
20
+ pageDataBase64: document.getElementById("__ELM_PAGES_BYTES_DATA__")
21
+ .innerHTML,
23
22
  userFlags: userInit.flags(),
24
23
  },
25
24
  });
@@ -48,48 +47,51 @@ function prefetchIfNeeded(/** @type {HTMLAnchorElement} */ target) {
48
47
  link.setAttribute("as", "fetch");
49
48
 
50
49
  link.setAttribute("rel", "prefetch");
51
- link.setAttribute("href", origin + target.pathname + "/content.json");
50
+ link.setAttribute("href", origin + target.pathname + "/content.dat");
52
51
  document.head.appendChild(link);
53
52
  }
54
53
  }
55
54
 
56
- const appPromise = new Promise(function (resolve, reject) {
57
- document.addEventListener("DOMContentLoaded", (_) => {
58
- resolve(loadContentAndInitializeApp());
59
- });
60
- });
61
-
62
- userInit.load(appPromise);
63
-
64
- if (typeof connect === "function") {
65
- connect(function (newContentJson) {
66
- appPromise.then((app) => {
67
- app.ports.fromJsPort.send({ contentJson: newContentJson });
55
+ export function setup() {
56
+ prefetchedPages = [window.location.pathname];
57
+ initialLocationHash = document.location.hash.replace(/^#/, "");
58
+ const appPromise = new Promise(function (resolve, reject) {
59
+ document.addEventListener("DOMContentLoaded", (_) => {
60
+ resolve(loadContentAndInitializeApp());
68
61
  });
69
62
  });
70
- }
63
+ userInit.load(appPromise);
71
64
 
72
- /** @param {MouseEvent} event */
73
- const trigger_prefetch = (event) => {
74
- const a = find_anchor(/** @type {Node} */ (event.target));
75
- if (a && a.href && a.hasAttribute("elm-pages:prefetch")) {
76
- prefetchIfNeeded(a);
65
+ if (typeof connect === "function") {
66
+ connect(function (bytesData) {
67
+ appPromise.then((app) => {
68
+ app.ports.hotReloadData.send(bytesData);
69
+ });
70
+ });
77
71
  }
78
- };
79
72
 
80
- /** @type {NodeJS.Timeout} */
81
- let mousemove_timeout;
73
+ /** @param {MouseEvent} event */
74
+ const trigger_prefetch = (event) => {
75
+ const a = find_anchor(/** @type {Node} */ (event.target));
76
+ if (a && a.href && a.hasAttribute("elm-pages:prefetch")) {
77
+ prefetchIfNeeded(a);
78
+ }
79
+ };
80
+
81
+ /** @type {NodeJS.Timeout} */
82
+ let mousemove_timeout;
82
83
 
83
- /** @param {MouseEvent} event */
84
- const handle_mousemove = (event) => {
85
- clearTimeout(mousemove_timeout);
86
- mousemove_timeout = setTimeout(() => {
87
- trigger_prefetch(event);
88
- }, 20);
89
- };
84
+ /** @param {MouseEvent} event */
85
+ const handle_mousemove = (event) => {
86
+ clearTimeout(mousemove_timeout);
87
+ mousemove_timeout = setTimeout(() => {
88
+ trigger_prefetch(event);
89
+ }, 20);
90
+ };
90
91
 
91
- addEventListener("touchstart", trigger_prefetch);
92
- addEventListener("mousemove", handle_mousemove);
92
+ addEventListener("touchstart", trigger_prefetch);
93
+ addEventListener("mousemove", handle_mousemove);
94
+ }
93
95
 
94
96
  /**
95
97
  * @param {Node} node
@@ -100,3 +102,5 @@ function find_anchor(node) {
100
102
  while (node && node.nodeName.toUpperCase() !== "A") node = node.parentNode; // SVG <a> elements have a lowercase name
101
103
  return /** @type {HTMLAnchorElement} */ (node);
102
104
  }
105
+
106
+ setup();