elm-pages 3.0.0-beta.4 → 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 (148) hide show
  1. package/README.md +10 -1
  2. package/adapter/netlify.js +207 -0
  3. package/codegen/{elm-pages-codegen.js → elm-pages-codegen.cjs} +2828 -2933
  4. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmi +0 -0
  5. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmo +0 -0
  6. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateDataTest.elmo +0 -0
  7. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  8. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  9. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  10. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm.json +1 -1
  11. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1447 -342
  12. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Runner.elm.js +17004 -13817
  13. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  14. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_supervisor.js +4 -4
  15. package/generator/dead-code-review/elm.json +9 -7
  16. package/generator/dead-code-review/src/Pages/Review/DeadCodeEliminateData.elm +59 -10
  17. package/generator/dead-code-review/tests/Pages/Review/DeadCodeEliminateDataTest.elm +52 -36
  18. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmi +0 -0
  19. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmo +0 -0
  20. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmi +0 -0
  21. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmo +0 -0
  22. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  23. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  24. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  25. package/generator/review/elm-stuff/tests-0.19.1/elm.json +1 -1
  26. package/generator/review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1447 -342
  27. package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +25025 -21739
  28. package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  29. package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +4 -4
  30. package/generator/review/elm.json +10 -10
  31. package/generator/src/RouteBuilder.elm +121 -114
  32. package/generator/src/SharedTemplate.elm +8 -7
  33. package/generator/src/SiteConfig.elm +3 -2
  34. package/generator/src/basepath-middleware.js +3 -3
  35. package/generator/src/build.js +209 -92
  36. package/generator/src/cli.js +292 -88
  37. package/generator/src/codegen.js +29 -27
  38. package/generator/src/compatibility-key.js +3 -0
  39. package/generator/src/compile-elm.js +43 -26
  40. package/generator/src/config.js +39 -0
  41. package/generator/src/copy-dir.js +2 -2
  42. package/generator/src/dev-server.js +176 -138
  43. package/generator/src/dir-helpers.js +9 -26
  44. package/generator/src/elm-codegen.js +5 -4
  45. package/generator/src/elm-file-constants.js +2 -3
  46. package/generator/src/error-formatter.js +12 -11
  47. package/generator/src/file-helpers.js +3 -4
  48. package/generator/src/generate-template-module-connector.js +23 -23
  49. package/generator/src/init.js +9 -8
  50. package/generator/src/pre-render-html.js +39 -28
  51. package/generator/src/render-test.js +109 -0
  52. package/generator/src/render-worker.js +25 -28
  53. package/generator/src/render.js +321 -142
  54. package/generator/src/request-cache.js +265 -162
  55. package/generator/src/resolve-elm-module.js +64 -0
  56. package/generator/src/rewrite-client-elm-json.js +6 -5
  57. package/generator/src/rewrite-elm-json-help.js +56 -0
  58. package/generator/src/rewrite-elm-json.js +17 -7
  59. package/generator/src/route-codegen-helpers.js +16 -31
  60. package/generator/src/seo-renderer.js +12 -7
  61. package/generator/src/vite-utils.js +77 -0
  62. package/generator/static-code/elm-pages.js +10 -0
  63. package/generator/static-code/hmr.js +79 -13
  64. package/generator/template/app/Api.elm +6 -5
  65. package/generator/template/app/Effect.elm +123 -0
  66. package/generator/template/app/ErrorPage.elm +37 -6
  67. package/generator/template/app/Route/Index.elm +17 -10
  68. package/generator/template/app/Shared.elm +24 -47
  69. package/generator/template/app/Site.elm +19 -6
  70. package/generator/template/app/View.elm +1 -8
  71. package/generator/template/elm-tooling.json +0 -3
  72. package/generator/template/elm.json +32 -24
  73. package/generator/template/package.json +10 -4
  74. package/package.json +30 -27
  75. package/src/ApiRoute.elm +199 -61
  76. package/src/BackendTask/Custom.elm +325 -0
  77. package/src/BackendTask/Env.elm +90 -0
  78. package/src/{DataSource → BackendTask}/File.elm +171 -56
  79. package/src/{DataSource → BackendTask}/Glob.elm +136 -125
  80. package/src/BackendTask/Http.elm +679 -0
  81. package/src/{DataSource → BackendTask}/Internal/Glob.elm +1 -1
  82. package/src/BackendTask/Internal/Request.elm +69 -0
  83. package/src/BackendTask/Random.elm +79 -0
  84. package/src/BackendTask/Time.elm +47 -0
  85. package/src/BackendTask.elm +531 -0
  86. package/src/FatalError.elm +90 -0
  87. package/src/Head/Seo.elm +4 -4
  88. package/src/Head.elm +237 -7
  89. package/src/HtmlPrinter.elm +7 -3
  90. package/src/Internal/ApiRoute.elm +7 -5
  91. package/src/PageServerResponse.elm +6 -1
  92. package/src/Pages/ConcurrentSubmission.elm +127 -0
  93. package/src/Pages/Form.elm +340 -0
  94. package/src/Pages/FormData.elm +18 -0
  95. package/src/Pages/GeneratorProgramConfig.elm +15 -0
  96. package/src/Pages/Internal/FatalError.elm +5 -0
  97. package/src/Pages/Internal/Msg.elm +93 -0
  98. package/src/Pages/Internal/NotFoundReason.elm +4 -4
  99. package/src/Pages/Internal/Platform/Cli.elm +617 -768
  100. package/src/Pages/Internal/Platform/CompatibilityKey.elm +6 -0
  101. package/src/Pages/Internal/Platform/Effect.elm +1 -2
  102. package/src/Pages/Internal/Platform/GeneratorApplication.elm +379 -0
  103. package/src/Pages/Internal/Platform/StaticResponses.elm +65 -276
  104. package/src/Pages/Internal/Platform/ToJsPayload.elm +6 -9
  105. package/src/Pages/Internal/Platform.elm +359 -225
  106. package/src/Pages/Internal/ResponseSketch.elm +2 -2
  107. package/src/Pages/Internal/Script.elm +17 -0
  108. package/src/Pages/Internal/StaticHttpBody.elm +35 -1
  109. package/src/Pages/Manifest.elm +52 -11
  110. package/src/Pages/Navigation.elm +87 -0
  111. package/src/Pages/PageUrl.elm +26 -12
  112. package/src/Pages/ProgramConfig.elm +35 -23
  113. package/src/Pages/Script.elm +166 -0
  114. package/src/Pages/SiteConfig.elm +3 -2
  115. package/src/Pages/StaticHttp/Request.elm +2 -2
  116. package/src/Pages/StaticHttpRequest.elm +23 -99
  117. package/src/Pages/Url.elm +3 -3
  118. package/src/PagesMsg.elm +88 -0
  119. package/src/QueryParams.elm +21 -172
  120. package/src/RenderRequest.elm +7 -7
  121. package/src/RequestsAndPending.elm +37 -20
  122. package/src/Result/Extra.elm +26 -0
  123. package/src/Scaffold/Form.elm +569 -0
  124. package/src/Scaffold/Route.elm +1411 -0
  125. package/src/Server/Request.elm +74 -72
  126. package/src/Server/Session.elm +62 -42
  127. package/src/Server/SetCookie.elm +80 -32
  128. package/src/Stub.elm +53 -0
  129. package/src/Test/Html/Internal/ElmHtml/ToString.elm +8 -9
  130. package/src/{Path.elm → UrlPath.elm} +33 -36
  131. package/src/DataSource/Env.elm +0 -38
  132. package/src/DataSource/Http.elm +0 -446
  133. package/src/DataSource/Internal/Request.elm +0 -20
  134. package/src/DataSource/Port.elm +0 -90
  135. package/src/DataSource.elm +0 -538
  136. package/src/Form/Field.elm +0 -717
  137. package/src/Form/FieldStatus.elm +0 -36
  138. package/src/Form/FieldView.elm +0 -417
  139. package/src/Form/FormData.elm +0 -22
  140. package/src/Form/Validation.elm +0 -391
  141. package/src/Form/Value.elm +0 -118
  142. package/src/Form.elm +0 -1683
  143. package/src/FormDecoder.elm +0 -102
  144. package/src/Pages/FormState.elm +0 -256
  145. package/src/Pages/Generate.elm +0 -800
  146. package/src/Pages/Internal/Form.elm +0 -17
  147. package/src/Pages/Msg.elm +0 -79
  148. package/src/Pages/Transition.elm +0 -70
@@ -0,0 +1,39 @@
1
+ import * as path from "path";
2
+
3
+ export async function resolveConfig() {
4
+ const initialConfig = await await import(
5
+ path.join(process.cwd(), "elm-pages.config.mjs")
6
+ )
7
+ .then(async (elmPagesConfig) => {
8
+ return (
9
+ elmPagesConfig.default || {
10
+ headTagsTemplate: defaultHeadTagsTemplate,
11
+ }
12
+ );
13
+ })
14
+ .catch((error) => {
15
+ console.warn(
16
+ "No `elm-pages.config.mjs` file found. Using default config."
17
+ );
18
+ return {
19
+ headTagsTemplate: defaultHeadTagsTemplate,
20
+ vite: {},
21
+ };
22
+ });
23
+
24
+ return {
25
+ preloadTagForFile: function () {
26
+ return true;
27
+ },
28
+ headTagsTemplate: defaultHeadTagsTemplate,
29
+ vite: {},
30
+ ...initialConfig,
31
+ };
32
+ }
33
+
34
+ function defaultHeadTagsTemplate(context) {
35
+ return `
36
+ <link rel="stylesheet" href="/style.css" />
37
+ <meta name="generator" content="elm-pages v${context.cliVersion}" />
38
+ `;
39
+ }
@@ -1,5 +1,5 @@
1
- const util = require("util");
2
- const fsSync = require("fs");
1
+ const util = require("node:util");
2
+ const fsSync = require("node:fs");
3
3
  const fs = {
4
4
  writeFile: util.promisify(fsSync.writeFile),
5
5
  mkdir: util.promisify(fsSync.mkdir),
@@ -1,36 +1,84 @@
1
- const path = require("path");
2
- const fs = require("fs");
3
- const which = require("which");
4
- const chokidar = require("chokidar");
5
- const { URL } = require("url");
6
- const {
1
+ import * as path from "path";
2
+ import * as fs from "fs";
3
+ import { default as which } from "which";
4
+ import * as chokidar from "chokidar";
5
+ import { URL } from "url";
6
+ import {
7
7
  compileElmForBrowser,
8
8
  runElmReview,
9
9
  compileCliApp,
10
- } = require("./compile-elm.js");
11
- const http = require("http");
12
- const https = require("https");
13
- const codegen = require("./codegen.js");
14
- const kleur = require("kleur");
15
- const serveStatic = require("serve-static");
16
- const connect = require("connect");
17
- const { restoreColorSafe } = require("./error-formatter");
18
- const { Worker, SHARE_ENV } = require("worker_threads");
19
- const os = require("os");
20
- const { ensureDirSync } = require("./file-helpers.js");
21
- const baseMiddleware = require("./basepath-middleware.js");
22
- const devcert = require("devcert");
23
- const busboy = require("busboy");
24
- const { createServer: createViteServer } = require("vite");
25
- const cliVersion = require("../../package.json").version;
26
- const esbuild = require("esbuild");
10
+ } from "./compile-elm.js";
11
+ import * as http from "http";
12
+ import * as https from "https";
13
+ import * as codegen from "./codegen.js";
14
+ import * as kleur from "kleur/colors";
15
+ import { default as serveStatic } from "serve-static";
16
+ import { default as connect } from "connect";
17
+ import { restoreColorSafe } from "./error-formatter.js";
18
+ import { Worker, SHARE_ENV } from "worker_threads";
19
+ import * as os from "os";
20
+ import { ensureDirSync } from "./file-helpers.js";
21
+ import { baseMiddleware } from "./basepath-middleware.js";
22
+ import * as devcert from "devcert";
23
+ import * as busboy from "busboy";
24
+ import { createServer as createViteServer } from "vite";
25
+ import * as esbuild from "esbuild";
26
+ import { merge_vite_configs } from "./vite-utils.js";
27
+ import { templateHtml } from "./pre-render-html.js";
28
+ import { resolveConfig } from "./config.js";
29
+ import * as globby from "globby";
30
+ import { fileURLToPath } from "url";
31
+
32
+ const __filename = fileURLToPath(import.meta.url);
33
+ const __dirname = path.dirname(__filename);
27
34
 
28
35
  /**
29
36
  * @param {{ port: string; base: string; https: boolean; debug: boolean; }} options
30
37
  */
31
- async function start(options) {
38
+ export async function start(options) {
39
+ console.error = function (...messages) {
40
+ if (!messages[0]?.startsWith("Failed to load url")) {
41
+ console.info(...messages);
42
+ }
43
+ };
44
+
32
45
  let threadReadyQueue = [];
33
46
  let pool = [];
47
+
48
+ function invalidatePool() {
49
+ pool.forEach((thread) => {
50
+ if (thread.used) {
51
+ thread.stale = true;
52
+ }
53
+ });
54
+ restartIdleWorkersIfStale();
55
+ }
56
+
57
+ function restartIdleWorkersIfStale() {
58
+ pool.forEach((thread) => {
59
+ if (thread.stale && thread.ready) {
60
+ reinitThread(thread);
61
+ }
62
+ });
63
+ }
64
+
65
+ function reinitThread(thisThread) {
66
+ thisThread.worker && thisThread.worker.terminate();
67
+ // TODO remove event listeners to avoid memory leak?
68
+ // thread.worker.removeAllListeners("message");
69
+ // thread.worker.removeAllListeners("error");
70
+ thisThread.ready = false;
71
+ thisThread.stale = false;
72
+ thisThread.used = false;
73
+ thisThread.worker = new Worker(path.join(__dirname, "./render-worker.js"), {
74
+ env: SHARE_ENV,
75
+ workerData: { basePath: options.base },
76
+ });
77
+ thisThread.worker.once("online", () => {
78
+ thisThread.ready = true;
79
+ });
80
+ }
81
+
34
82
  ensureDirSync(path.join(process.cwd(), ".elm-pages", "http-response-cache"));
35
83
  const cpuCount = os.cpus().length;
36
84
 
@@ -42,6 +90,7 @@ async function start(options) {
42
90
  const serveCachedFiles = serveStatic(".elm-pages/cache", { index: false });
43
91
  const generatedFilesDirectory = "elm-stuff/elm-pages/generated-files";
44
92
  fs.mkdirSync(generatedFilesDirectory, { recursive: true });
93
+
45
94
  const serveStaticCode = serveStatic(
46
95
  path.join(__dirname, "../static-code"),
47
96
  {}
@@ -117,63 +166,86 @@ async function start(options) {
117
166
  watcher.add(sourceDirs);
118
167
  }
119
168
 
120
- const viteConfig = await import(
121
- path.join(process.cwd(), "elm-pages.config.mjs")
122
- )
123
- .then(async (elmPagesConfig) => {
124
- return elmPagesConfig.default.vite || {};
125
- })
126
- .catch((error) => {
127
- console.warn(
128
- kleur.yellow(
129
- "No `elm-pages.config.mjs` file found. Using default config."
130
- )
131
- );
132
- return {};
133
- });
134
- const vite = await createViteServer({
135
- server: { middlewareMode: "ssr", base: options.base, port: options.port },
136
- configFile: false,
137
- root: process.cwd(),
138
- base: options.base,
139
- ...viteConfig,
140
- });
141
- esbuild
142
- .build({
143
- entryPoints: ["./port-data-source"],
144
- platform: "node",
145
- assetNames: "[name]-[hash]",
146
- chunkNames: "chunks/[name]-[hash]",
147
- outExtension: { ".js": ".js" },
148
- metafile: true,
149
- bundle: true,
150
- watch: true,
151
- logLevel: "error",
152
-
153
- outdir: ".elm-pages/compiled-ports",
154
- entryNames: "[dir]/[name]-[hash]",
155
-
156
- plugins: [
157
- {
158
- name: "example",
159
- setup(build) {
160
- build.onEnd((result) => {
169
+ const config = await resolveConfig();
170
+ const vite = await createViteServer(
171
+ merge_vite_configs(
172
+ {
173
+ server: {
174
+ middlewareMode: true,
175
+ base: options.base,
176
+ port: options.port,
177
+ },
178
+ appType: "custom",
179
+ configFile: false,
180
+ root: process.cwd(),
181
+ base: options.base,
182
+ /*
183
+ Using explicit optimizeDeps.include prevents the following Vite warning message:
184
+ (!) Could not auto-determine entry point from rollupOptions or html files and there are no explicit optimizeDeps.include patterns. Skipping dependency pre-bundling.
185
+ */
186
+ optimizeDeps: {
187
+ include: [],
188
+ },
189
+ },
190
+
191
+ config.vite
192
+ )
193
+ );
194
+
195
+ const ctx = await esbuild.context({
196
+ entryPoints: ["./custom-backend-task"],
197
+ platform: "node",
198
+ assetNames: "[name]-[hash]",
199
+ chunkNames: "chunks/[name]-[hash]",
200
+ outExtension: { ".js": ".mjs" },
201
+ format: "esm",
202
+ metafile: true,
203
+ bundle: true,
204
+ packages: "external",
205
+ logLevel: "silent",
206
+ outdir: ".elm-pages/compiled-ports",
207
+ entryNames: "[dir]/[name]-[hash]",
208
+
209
+ plugins: [
210
+ {
211
+ name: "example",
212
+ setup(build) {
213
+ build.onEnd(async (result) => {
214
+ try {
161
215
  global.portsFilePath = Object.keys(result.metafile.outputs)[0];
162
216
 
163
217
  clients.forEach((client) => {
164
218
  client.response.write(`data: content.dat\n\n`);
165
219
  });
166
- });
167
- },
220
+ } catch (e) {
221
+ const portBackendTaskFileFound =
222
+ globby.globbySync("./custom-backend-task.*").length > 0;
223
+ if (portBackendTaskFileFound) {
224
+ // don't present error if there are no files matching custom-backend-task
225
+ // if there are files matching custom-backend-task, warn the user in case something went wrong loading it
226
+ const messages = (
227
+ await esbuild.formatMessages(result.errors, {
228
+ kind: "error",
229
+ color: true,
230
+ })
231
+ ).join("\n");
232
+ global.portsFilePath = {
233
+ __internalElmPagesError: messages,
234
+ };
235
+
236
+ clients.forEach((client) => {
237
+ client.response.write(`data: content.dat\n\n`);
238
+ });
239
+ } else {
240
+ global.portsFilePath = null;
241
+ }
242
+ }
243
+ });
168
244
  },
169
- ],
170
- })
171
- .then((result) => {
172
- console.log("Watching port-data-source...");
173
- })
174
- .catch((error) => {
175
- console.error("Failed to start port-data-source watcher", error);
176
- });
245
+ },
246
+ ],
247
+ });
248
+ await ctx.watch();
177
249
 
178
250
  const app = connect()
179
251
  .use(timeMiddleware())
@@ -206,33 +278,19 @@ async function start(options) {
206
278
  watcher.on("all", async function (eventName, pathThatChanged) {
207
279
  if (pathThatChanged === "elm.json") {
208
280
  watchElmSourceDirs(false);
281
+ } else if (
282
+ pathThatChanged.startsWith("app/Route") &&
283
+ !pathThatChanged.endsWith(".elm")
284
+ ) {
285
+ // this happens when a folder is created in app/Route. Ignore this case.
209
286
  } else if (pathThatChanged.endsWith(".elm")) {
287
+ invalidatePool();
210
288
  if (elmMakeRunning) {
211
289
  } else {
212
290
  let codegenError = null;
213
291
  if (needToRerunCodegen(eventName, pathThatChanged)) {
214
292
  try {
215
293
  await codegen.generate(options.base);
216
- clientElmMakeProcess = compileElmForBrowser(options);
217
- pendingCliCompile = compileCliApp(
218
- options,
219
- ".elm-pages/Main.elm",
220
- path.join(process.cwd(), "elm-stuff/elm-pages/", "elm.js"),
221
- // "elm.js",
222
- "elm-stuff/elm-pages/",
223
- path.join("elm-stuff/elm-pages/", "elm.js")
224
- );
225
-
226
- Promise.all([clientElmMakeProcess, pendingCliCompile])
227
- .then(() => {
228
- elmMakeRunning = false;
229
- })
230
- .catch(() => {
231
- elmMakeRunning = false;
232
- });
233
- clients.forEach((client) => {
234
- client.response.write(`data: elm.js\n\n`);
235
- });
236
294
  } catch (error) {
237
295
  codegenError = error;
238
296
  }
@@ -250,10 +308,7 @@ async function start(options) {
250
308
  pendingCliCompile = compileCliApp(
251
309
  options,
252
310
  ".elm-pages/Main.elm",
253
-
254
311
  path.join(process.cwd(), "elm-stuff/elm-pages/", "elm.js"),
255
-
256
- // "elm.js",
257
312
  "elm-stuff/elm-pages/",
258
313
  path.join("elm-stuff/elm-pages/", "elm.js")
259
314
  );
@@ -274,18 +329,18 @@ async function start(options) {
274
329
  // TODO use similar logic in the workers? Or don't use cache at all?
275
330
  // const changedPathRelative = path.relative(process.cwd(), pathThatChanged);
276
331
  //
277
- // Object.keys(global.staticHttpCache).forEach((dataSourceKey) => {
278
- // if (dataSourceKey.includes(`file://${changedPathRelative}`)) {
279
- // delete global.staticHttpCache[dataSourceKey];
332
+ // Object.keys(global.staticHttpCache).forEach((backendTaskKey) => {
333
+ // if (backendTaskKey.includes(`file://${changedPathRelative}`)) {
334
+ // delete global.staticHttpCache[backendTaskKey];
280
335
  // } else if (
281
336
  // (eventName === "add" ||
282
337
  // eventName === "unlink" ||
283
338
  // eventName === "change" ||
284
339
  // eventName === "addDir" ||
285
340
  // eventName === "unlinkDir") &&
286
- // dataSourceKey.startsWith("glob://")
341
+ // backendTaskKey.startsWith("glob://")
287
342
  // ) {
288
- // delete global.staticHttpCache[dataSourceKey];
343
+ // delete global.staticHttpCache[backendTaskKey];
289
344
  // }
290
345
  // });
291
346
  clients.forEach((client) => {
@@ -336,6 +391,8 @@ async function start(options) {
336
391
  };
337
392
 
338
393
  readyThread.ready = false;
394
+ await pendingCliCompile;
395
+ readyThread.used = true;
339
396
  readyThread.worker.postMessage({
340
397
  mode: "dev-server",
341
398
  pathname,
@@ -459,35 +516,7 @@ async function start(options) {
459
516
  }
460
517
  case "html": {
461
518
  try {
462
- const template =
463
- /*html*/
464
- `<!DOCTYPE html>
465
- <!-- ROOT --><html lang="en">
466
- <head>
467
- <script src="/hmr.js" type="text/javascript"></script>
468
- <script src="/elm.js" type="text/javascript"></script>
469
- <link rel="stylesheet" href="/style.css">
470
- <link rel="stylesheet" href="/dev-style.css">
471
- <script src="/elm-pages.js" type="module"></script>
472
- <meta charset="UTF-8" />
473
- <meta name="viewport" content="width=device-width,initial-scale=1" />
474
- <title><!-- PLACEHOLDER_TITLE --></title>
475
- <meta name="generator" content="elm-pages v${cliVersion}" />
476
- <meta name="mobile-web-app-capable" content="yes" />
477
- <meta name="theme-color" content="#ffffff" />
478
- <meta name="apple-mobile-web-app-capable" content="yes" />
479
- <meta
480
- name="apple-mobile-web-app-status-bar-style"
481
- content="black-translucent"
482
- />
483
- <!-- PLACEHOLDER_HEAD_AND_DATA -->
484
- </head>
485
- <body>
486
- <div data-url="" display="none"></div>
487
- <!-- PLACEHOLDER_HTML -->
488
- </body>
489
- </html>
490
- `;
519
+ const template = templateHtml(true, config.headTagsTemplate);
491
520
  const processedTemplate = await vite.transformIndexHtml(
492
521
  req.originalUrl,
493
522
  template
@@ -505,9 +534,9 @@ async function start(options) {
505
534
  /<!-- ROOT -->\S*<html lang="en">/m,
506
535
  info.rootElement
507
536
  );
537
+ setHeaders(res, renderResult.headers);
508
538
  res.writeHead(renderResult.statusCode, {
509
539
  "Content-Type": "text/html",
510
- ...renderResult.headers,
511
540
  });
512
541
  res.end(renderedHtml);
513
542
  } catch (e) {
@@ -519,10 +548,8 @@ async function start(options) {
519
548
  case "api-response": {
520
549
  if (renderResult.body.kind === "server-response") {
521
550
  const serverResponse = renderResult.body;
522
- res.writeHead(
523
- serverResponse.statusCode,
524
- serverResponse.headers
525
- );
551
+ setHeaders(res, serverResponse.headers);
552
+ res.writeHead(serverResponse.statusCode);
526
553
  res.end(serverResponse.body);
527
554
  } else if (renderResult.body.kind === "static-file") {
528
555
  let mimeType = serveStatic.mime.lookup(pathname || "text/html");
@@ -565,6 +592,16 @@ async function start(options) {
565
592
  });
566
593
  }
567
594
 
595
+ /**
596
+ * @param { http.ServerResponse } res
597
+ * @param {{ [key: string]: string[]; }} headers
598
+ */
599
+ function setHeaders(res, headers) {
600
+ Object.keys(headers).forEach(function (key) {
601
+ res.setHeader(key, headers[key]);
602
+ });
603
+ }
604
+
568
605
  /**
569
606
  * @param {string} reviewReportJsonString
570
607
  */
@@ -610,6 +647,7 @@ async function start(options) {
610
647
  }
611
648
 
612
649
  function runPendingWork() {
650
+ restartIdleWorkersIfStale();
613
651
  const readyThreads = pool.filter((thread) => thread.ready);
614
652
  readyThreads.forEach((readyThread) => {
615
653
  const startTask = threadReadyQueue.shift();
@@ -634,6 +672,7 @@ async function start(options) {
634
672
  workerData: { basePath },
635
673
  }),
636
674
  ready: false,
675
+ used: false,
637
676
  };
638
677
  newWorker.worker.once("online", () => {
639
678
  newWorker.ready = true;
@@ -804,4 +843,3 @@ function paramsToObject(entries) {
804
843
  }
805
844
  return result;
806
845
  }
807
- module.exports = { start };
@@ -1,5 +1,7 @@
1
- const util = require("util");
2
- const fsSync = require("fs");
1
+ import * as util from "node:util";
2
+ import * as fsSync from "node:fs";
3
+ import * as path from "node:path";
4
+
3
5
  const fs = {
4
6
  writeFile: util.promisify(fsSync.writeFile),
5
7
  writeFileSync: fsSync.writeFileSync,
@@ -15,14 +17,14 @@ const fs = {
15
17
  /**
16
18
  * @param {import("fs").PathLike} dirName
17
19
  */
18
- async function tryMkdir(dirName) {
20
+ export async function tryMkdir(dirName) {
19
21
  const exists = await fs.exists(dirName);
20
22
  if (!exists) {
21
23
  await fs.mkdir(dirName, { recursive: true });
22
24
  }
23
25
  }
24
26
 
25
- function fileExists(file) {
27
+ export function fileExists(file) {
26
28
  return fsSync.promises
27
29
  .access(file, fsSync.constants.F_OK)
28
30
  .then(() => true)
@@ -33,18 +35,16 @@ function fileExists(file) {
33
35
  * @param {string} filePath
34
36
  * @param {string} data
35
37
  */
36
- function writeFileSyncSafe(filePath, data) {
38
+ export function writeFileSyncSafe(filePath, data) {
37
39
  fsSync.mkdirSync(path.dirname(filePath), { recursive: true });
38
40
  fs.writeFileSync(filePath, data);
39
41
  }
40
42
 
41
- const path = require("path");
42
-
43
43
  /**
44
44
  * @param {string} srcDirectory
45
45
  * @param {string} destDir
46
46
  */
47
- async function copyDirFlat(srcDirectory, destDir) {
47
+ export async function copyDirFlat(srcDirectory, destDir) {
48
48
  const items = await fs.readdir(srcDirectory);
49
49
  items.forEach(function (childItemName) {
50
50
  copyDirNested(
@@ -58,7 +58,7 @@ async function copyDirFlat(srcDirectory, destDir) {
58
58
  * @param {string} src
59
59
  * @param {string} dest
60
60
  */
61
- async function copyDirNested(src, dest) {
61
+ export async function copyDirNested(src, dest) {
62
62
  var exists = fsSync.existsSync(src);
63
63
  var stats = exists && fsSync.statSync(src);
64
64
  var isDirectory = exists && stats.isDirectory();
@@ -75,20 +75,3 @@ async function copyDirNested(src, dest) {
75
75
  fs.copyFile(src, dest);
76
76
  }
77
77
  }
78
-
79
- module.exports = {
80
- writeFile: fs.writeFile,
81
- writeFileSync: fs.writeFileSync,
82
- readFile: fs.readFile,
83
- readFileSync: fsSync.readFileSync,
84
- copyFile: fs.copyFile,
85
- exists: fs.exists,
86
- writeFileSyncSafe,
87
- tryMkdir,
88
- copyDirFlat,
89
- copyDirNested,
90
- rmSync: fs.rm,
91
- rm: fs.rm,
92
- existsSync: fs.existsSync,
93
- fileExists: fileExists,
94
- };
@@ -1,6 +1,6 @@
1
- const spawnCallback = require("cross-spawn").spawn;
1
+ import { spawn as spawnCallback } from "cross-spawn";
2
2
 
3
- function runElmCodegenInstall() {
3
+ export function runElmCodegenInstall() {
4
4
  return new Promise(async (resolve, reject) => {
5
5
  const subprocess = spawnCallback(`elm-codegen`, ["install"], {
6
6
  // ignore stdout
@@ -17,6 +17,9 @@ function runElmCodegenInstall() {
17
17
  subprocess.stderr.on("data", function (data) {
18
18
  commandOutput += data;
19
19
  });
20
+ subprocess.stdout.on("data", function (data) {
21
+ commandOutput += data;
22
+ });
20
23
  subprocess.on("error", function () {
21
24
  reject(commandOutput);
22
25
  });
@@ -30,5 +33,3 @@ function runElmCodegenInstall() {
30
33
  });
31
34
  });
32
35
  }
33
-
34
- module.exports = { runElmCodegenInstall };
@@ -1,4 +1,4 @@
1
- function elmPagesUiFile() {
1
+ export function elmPagesUiFile() {
2
2
  return `module Pages exposing (builtAt)
3
3
 
4
4
  import Time
@@ -12,7 +12,6 @@ builtAt =
12
12
  `;
13
13
  }
14
14
 
15
- function elmPagesCliFile() {
15
+ export function elmPagesCliFile() {
16
16
  return elmPagesUiFile();
17
17
  }
18
- module.exports = { elmPagesUiFile, elmPagesCliFile };
@@ -1,4 +1,6 @@
1
- const kleur = require("kleur");
1
+ "use strict";
2
+
3
+ import * as kleur from "kleur/colors";
2
4
 
3
5
  /* Thanks to elm-live for this code!
4
6
  https://github.com/wking-io/elm-live/blob/e317b4914c471addea7243c47f28dcebe27a5d36/lib/src/build.js#L65
@@ -13,11 +15,12 @@ const kleur = require("kleur");
13
15
  * @param {string} rule
14
16
  * @param {string} path
15
17
  * */
16
- const parseHeader = (rule, path) =>
17
- kleur.cyan(
18
- `-- ${rule.replace("-", " ")} --------------- ${path || ""}
18
+ function parseHeader(rule, path) {
19
+ return kleur.cyan(
20
+ `-- ${(rule || "").replace("-", " ")} --------------- ${path || ""}
19
21
  `
20
22
  );
23
+ }
21
24
 
22
25
  /**
23
26
  * parseMsg :: String|Object -> String
@@ -55,9 +58,6 @@ function toKleurColor(color) {
55
58
  case "33BBC8": {
56
59
  return "cyan";
57
60
  }
58
- case "33BBC8": {
59
- return "cyan";
60
- }
61
61
  case "FFFF00": {
62
62
  return "yellow";
63
63
  }
@@ -81,7 +81,7 @@ function toKleurColor(color) {
81
81
  /**
82
82
  * @param {RootObject} error
83
83
  * */
84
- const restoreColor = (error) => {
84
+ export const restoreColor = (error) => {
85
85
  try {
86
86
  if (error.type === "compile-errors") {
87
87
  return error.errors
@@ -110,7 +110,7 @@ const restoreColor = (error) => {
110
110
  * @param {string} error
111
111
  * @returns {string}
112
112
  */
113
- function restoreColorSafe(error) {
113
+ export function restoreColorSafe(error) {
114
114
  try {
115
115
  if (typeof error === "string") {
116
116
  const asJson = JSON.parse(error);
@@ -137,7 +137,10 @@ const restoreProblem =
137
137
  parseHeader(info.rule, path),
138
138
  ...info.formatted.map(parseMsg),
139
139
  ].join("");
140
+ } else if (typeof info.message === "string") {
141
+ return info.message;
140
142
  } else {
143
+ // console.log("info.message", info.message);
141
144
  return [
142
145
  parseHeader(info.title, path),
143
146
  ...info.message.map(parseMsg),
@@ -145,8 +148,6 @@ const restoreProblem =
145
148
  }
146
149
  };
147
150
 
148
- module.exports = { restoreColor, restoreColorSafe };
149
-
150
151
  /** @typedef { CompilerError | ReportError | IElmReviewError } RootObject */
151
152
 
152
153
  /** @typedef { { type: "compile-errors"; errors: Error_[]; } } CompilerError */