elm-pages 3.0.0-beta.9 → 3.0.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.
- package/README.md +2 -2
- package/adapter/netlify.js +207 -0
- package/codegen/{elm-pages-codegen.js → elm-pages-codegen.cjs} +2731 -2939
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmi +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmo +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateDataTest.elmo +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm.json +1 -1
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1527 -422
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Runner.elm.js +16840 -13653
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_supervisor.js +4 -4
- package/generator/dead-code-review/elm.json +9 -7
- package/generator/dead-code-review/src/Pages/Review/DeadCodeEliminateData.elm +59 -10
- package/generator/dead-code-review/tests/Pages/Review/DeadCodeEliminateDataTest.elm +52 -36
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmi +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmo +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmi +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmo +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm.json +1 -1
- package/generator/review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1527 -422
- package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +25118 -21832
- package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
- package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +4 -4
- package/generator/review/elm.json +10 -10
- package/generator/src/RouteBuilder.elm +93 -128
- package/generator/src/SharedTemplate.elm +8 -7
- package/generator/src/SiteConfig.elm +3 -2
- package/generator/src/basepath-middleware.js +3 -3
- package/generator/src/build.js +143 -59
- package/generator/src/cli.js +292 -88
- package/generator/src/codegen.js +29 -27
- package/generator/src/compatibility-key.js +3 -0
- package/generator/src/compile-elm.js +43 -26
- package/generator/src/config.js +2 -4
- package/generator/src/copy-dir.js +2 -2
- package/generator/src/dev-server.js +160 -102
- package/generator/src/dir-helpers.js +9 -26
- package/generator/src/elm-codegen.js +5 -4
- package/generator/src/elm-file-constants.js +2 -3
- package/generator/src/error-formatter.js +12 -11
- package/generator/src/file-helpers.js +3 -4
- package/generator/src/generate-template-module-connector.js +23 -23
- package/generator/src/init.js +9 -8
- package/generator/src/pre-render-html.js +10 -13
- package/generator/src/render-test.js +109 -0
- package/generator/src/render-worker.js +25 -28
- package/generator/src/render.js +320 -143
- package/generator/src/request-cache.js +265 -162
- package/generator/src/resolve-elm-module.js +64 -0
- package/generator/src/rewrite-client-elm-json.js +6 -5
- package/generator/src/rewrite-elm-json-help.js +56 -0
- package/generator/src/rewrite-elm-json.js +17 -7
- package/generator/src/route-codegen-helpers.js +16 -31
- package/generator/src/seo-renderer.js +1 -3
- package/generator/src/vite-utils.js +1 -2
- package/generator/static-code/elm-pages.js +10 -0
- package/generator/static-code/hmr.js +79 -13
- package/generator/template/app/Api.elm +3 -2
- package/generator/template/app/Effect.elm +155 -0
- package/generator/template/app/ErrorPage.elm +49 -6
- package/generator/template/app/Route/Blog/Slug_.elm +86 -0
- package/generator/template/app/Route/Greet.elm +107 -0
- package/generator/template/app/Route/Hello.elm +119 -0
- package/generator/template/app/Route/Index.elm +26 -25
- package/generator/template/app/Shared.elm +38 -39
- package/generator/template/app/Site.elm +4 -7
- package/generator/template/app/View.elm +9 -8
- package/generator/template/codegen/elm.codegen.json +18 -0
- package/generator/template/custom-backend-task.ts +3 -0
- package/generator/template/elm-pages.config.mjs +13 -0
- package/generator/template/elm-tooling.json +0 -3
- package/generator/template/elm.json +25 -20
- package/generator/template/index.ts +1 -2
- package/generator/template/netlify.toml +4 -1
- package/generator/template/package.json +10 -4
- package/generator/template/script/.elm-pages/compiled-ports/custom-backend-task.mjs +7 -0
- package/generator/template/script/custom-backend-task.ts +3 -0
- package/generator/template/script/elm.json +61 -0
- package/generator/template/script/src/AddRoute.elm +312 -0
- package/generator/template/script/src/Stars.elm +42 -0
- package/package.json +30 -27
- package/src/ApiRoute.elm +249 -82
- package/src/BackendTask/Custom.elm +325 -0
- package/src/BackendTask/Env.elm +90 -0
- package/src/{DataSource → BackendTask}/File.elm +171 -56
- package/src/{DataSource → BackendTask}/Glob.elm +136 -125
- package/src/BackendTask/Http.elm +679 -0
- package/src/{DataSource → BackendTask}/Internal/Glob.elm +1 -1
- package/src/BackendTask/Internal/Request.elm +69 -0
- package/src/BackendTask/Random.elm +79 -0
- package/src/BackendTask/Time.elm +47 -0
- package/src/BackendTask.elm +531 -0
- package/src/FatalError.elm +90 -0
- package/src/FormData.elm +21 -18
- package/src/Head/Seo.elm +4 -4
- package/src/Head.elm +112 -8
- package/src/Internal/ApiRoute.elm +7 -5
- package/src/Internal/Request.elm +84 -4
- package/src/PageServerResponse.elm +6 -1
- package/src/Pages/ConcurrentSubmission.elm +127 -0
- package/src/Pages/Form.elm +340 -0
- package/src/Pages/FormData.elm +19 -0
- package/src/Pages/GeneratorProgramConfig.elm +15 -0
- package/src/Pages/Internal/FatalError.elm +5 -0
- package/src/Pages/Internal/Msg.elm +93 -0
- package/src/Pages/Internal/NotFoundReason.elm +4 -4
- package/src/Pages/Internal/Platform/Cli.elm +586 -768
- package/src/Pages/Internal/Platform/CompatibilityKey.elm +1 -1
- package/src/Pages/Internal/Platform/Effect.elm +1 -2
- package/src/Pages/Internal/Platform/GeneratorApplication.elm +379 -0
- package/src/Pages/Internal/Platform/StaticResponses.elm +65 -276
- package/src/Pages/Internal/Platform/ToJsPayload.elm +6 -9
- package/src/Pages/Internal/Platform.elm +330 -203
- package/src/Pages/Internal/ResponseSketch.elm +2 -2
- package/src/Pages/Internal/Script.elm +17 -0
- package/src/Pages/Internal/StaticHttpBody.elm +35 -1
- package/src/Pages/Manifest.elm +52 -11
- package/src/Pages/Navigation.elm +85 -0
- package/src/Pages/PageUrl.elm +26 -12
- package/src/Pages/ProgramConfig.elm +32 -22
- package/src/Pages/Script.elm +166 -0
- package/src/Pages/SiteConfig.elm +3 -2
- package/src/Pages/StaticHttp/Request.elm +2 -2
- package/src/Pages/StaticHttpRequest.elm +23 -99
- package/src/Pages/Url.elm +3 -3
- package/src/PagesMsg.elm +88 -0
- package/src/QueryParams.elm +21 -172
- package/src/RenderRequest.elm +7 -7
- package/src/RequestsAndPending.elm +37 -20
- package/src/Result/Extra.elm +26 -0
- package/src/Scaffold/Form.elm +569 -0
- package/src/Scaffold/Route.elm +1431 -0
- package/src/Server/Request.elm +476 -1001
- package/src/Server/Response.elm +130 -36
- package/src/Server/Session.elm +181 -111
- package/src/Server/SetCookie.elm +80 -32
- package/src/Stub.elm +53 -0
- package/src/Test/Html/Internal/ElmHtml/ToString.elm +8 -9
- package/src/{Path.elm → UrlPath.elm} +33 -36
- package/generator/template/public/images/icon-png.png +0 -0
- package/src/DataSource/Env.elm +0 -38
- package/src/DataSource/Http.elm +0 -446
- package/src/DataSource/Internal/Request.elm +0 -20
- package/src/DataSource/Port.elm +0 -90
- package/src/DataSource.elm +0 -546
- package/src/Form/Field.elm +0 -717
- package/src/Form/FieldStatus.elm +0 -36
- package/src/Form/FieldView.elm +0 -417
- package/src/Form/FormData.elm +0 -22
- package/src/Form/Validation.elm +0 -391
- package/src/Form/Value.elm +0 -118
- package/src/Form.elm +0 -1683
- package/src/FormDecoder.elm +0 -102
- package/src/Pages/FormState.elm +0 -256
- package/src/Pages/Generate.elm +0 -1242
- package/src/Pages/Internal/Form.elm +0 -17
- package/src/Pages/Internal/Platform/Cli.elm.bak +0 -1276
- package/src/Pages/Msg.elm +0 -79
- package/src/Pages/Transition.elm +0 -70
|
@@ -1,40 +1,84 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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
|
-
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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);
|
|
31
34
|
|
|
32
35
|
/**
|
|
33
36
|
* @param {{ port: string; base: string; https: boolean; debug: boolean; }} options
|
|
34
37
|
*/
|
|
35
|
-
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
|
+
|
|
36
45
|
let threadReadyQueue = [];
|
|
37
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
|
+
|
|
38
82
|
ensureDirSync(path.join(process.cwd(), ".elm-pages", "http-response-cache"));
|
|
39
83
|
const cpuCount = os.cpus().length;
|
|
40
84
|
|
|
@@ -46,6 +90,7 @@ async function start(options) {
|
|
|
46
90
|
const serveCachedFiles = serveStatic(".elm-pages/cache", { index: false });
|
|
47
91
|
const generatedFilesDirectory = "elm-stuff/elm-pages/generated-files";
|
|
48
92
|
fs.mkdirSync(generatedFilesDirectory, { recursive: true });
|
|
93
|
+
|
|
49
94
|
const serveStaticCode = serveStatic(
|
|
50
95
|
path.join(__dirname, "../static-code"),
|
|
51
96
|
{}
|
|
@@ -126,62 +171,81 @@ async function start(options) {
|
|
|
126
171
|
merge_vite_configs(
|
|
127
172
|
{
|
|
128
173
|
server: {
|
|
129
|
-
middlewareMode:
|
|
174
|
+
middlewareMode: true,
|
|
130
175
|
base: options.base,
|
|
131
176
|
port: options.port,
|
|
132
177
|
},
|
|
178
|
+
appType: "custom",
|
|
133
179
|
configFile: false,
|
|
134
180
|
root: process.cwd(),
|
|
135
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
|
+
},
|
|
136
189
|
},
|
|
137
190
|
|
|
138
191
|
config.vite
|
|
139
192
|
)
|
|
140
193
|
);
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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 {
|
|
215
|
+
global.portsFilePath = Object.keys(result.metafile.outputs)[0];
|
|
216
|
+
|
|
217
|
+
clients.forEach((client) => {
|
|
218
|
+
client.response.write(`data: content.dat\n\n`);
|
|
219
|
+
});
|
|
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
|
+
};
|
|
163
235
|
|
|
164
236
|
clients.forEach((client) => {
|
|
165
237
|
client.response.write(`data: content.dat\n\n`);
|
|
166
238
|
});
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
|
|
239
|
+
} else {
|
|
240
|
+
global.portsFilePath = null;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
});
|
|
170
244
|
},
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
})
|
|
176
|
-
.catch((error) => {
|
|
177
|
-
const portDataSourceFileFound =
|
|
178
|
-
globby.sync("./port-data-source.*").length > 0;
|
|
179
|
-
if (portDataSourceFileFound) {
|
|
180
|
-
// don't present error if there are no files matching port-data-source
|
|
181
|
-
// if there are files matching port-data-source, warn the user in case something went wrong loading it
|
|
182
|
-
console.error("Failed to start port-data-source watcher", error);
|
|
183
|
-
}
|
|
184
|
-
});
|
|
245
|
+
},
|
|
246
|
+
],
|
|
247
|
+
});
|
|
248
|
+
await ctx.watch();
|
|
185
249
|
|
|
186
250
|
const app = connect()
|
|
187
251
|
.use(timeMiddleware())
|
|
@@ -214,33 +278,19 @@ async function start(options) {
|
|
|
214
278
|
watcher.on("all", async function (eventName, pathThatChanged) {
|
|
215
279
|
if (pathThatChanged === "elm.json") {
|
|
216
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.
|
|
217
286
|
} else if (pathThatChanged.endsWith(".elm")) {
|
|
287
|
+
invalidatePool();
|
|
218
288
|
if (elmMakeRunning) {
|
|
219
289
|
} else {
|
|
220
290
|
let codegenError = null;
|
|
221
291
|
if (needToRerunCodegen(eventName, pathThatChanged)) {
|
|
222
292
|
try {
|
|
223
293
|
await codegen.generate(options.base);
|
|
224
|
-
clientElmMakeProcess = compileElmForBrowser(options);
|
|
225
|
-
pendingCliCompile = compileCliApp(
|
|
226
|
-
options,
|
|
227
|
-
".elm-pages/Main.elm",
|
|
228
|
-
path.join(process.cwd(), "elm-stuff/elm-pages/", "elm.js"),
|
|
229
|
-
// "elm.js",
|
|
230
|
-
"elm-stuff/elm-pages/",
|
|
231
|
-
path.join("elm-stuff/elm-pages/", "elm.js")
|
|
232
|
-
);
|
|
233
|
-
|
|
234
|
-
Promise.all([clientElmMakeProcess, pendingCliCompile])
|
|
235
|
-
.then(() => {
|
|
236
|
-
elmMakeRunning = false;
|
|
237
|
-
})
|
|
238
|
-
.catch(() => {
|
|
239
|
-
elmMakeRunning = false;
|
|
240
|
-
});
|
|
241
|
-
clients.forEach((client) => {
|
|
242
|
-
client.response.write(`data: elm.js\n\n`);
|
|
243
|
-
});
|
|
244
294
|
} catch (error) {
|
|
245
295
|
codegenError = error;
|
|
246
296
|
}
|
|
@@ -258,10 +308,7 @@ async function start(options) {
|
|
|
258
308
|
pendingCliCompile = compileCliApp(
|
|
259
309
|
options,
|
|
260
310
|
".elm-pages/Main.elm",
|
|
261
|
-
|
|
262
311
|
path.join(process.cwd(), "elm-stuff/elm-pages/", "elm.js"),
|
|
263
|
-
|
|
264
|
-
// "elm.js",
|
|
265
312
|
"elm-stuff/elm-pages/",
|
|
266
313
|
path.join("elm-stuff/elm-pages/", "elm.js")
|
|
267
314
|
);
|
|
@@ -282,18 +329,18 @@ async function start(options) {
|
|
|
282
329
|
// TODO use similar logic in the workers? Or don't use cache at all?
|
|
283
330
|
// const changedPathRelative = path.relative(process.cwd(), pathThatChanged);
|
|
284
331
|
//
|
|
285
|
-
// Object.keys(global.staticHttpCache).forEach((
|
|
286
|
-
// if (
|
|
287
|
-
// delete global.staticHttpCache[
|
|
332
|
+
// Object.keys(global.staticHttpCache).forEach((backendTaskKey) => {
|
|
333
|
+
// if (backendTaskKey.includes(`file://${changedPathRelative}`)) {
|
|
334
|
+
// delete global.staticHttpCache[backendTaskKey];
|
|
288
335
|
// } else if (
|
|
289
336
|
// (eventName === "add" ||
|
|
290
337
|
// eventName === "unlink" ||
|
|
291
338
|
// eventName === "change" ||
|
|
292
339
|
// eventName === "addDir" ||
|
|
293
340
|
// eventName === "unlinkDir") &&
|
|
294
|
-
//
|
|
341
|
+
// backendTaskKey.startsWith("glob://")
|
|
295
342
|
// ) {
|
|
296
|
-
// delete global.staticHttpCache[
|
|
343
|
+
// delete global.staticHttpCache[backendTaskKey];
|
|
297
344
|
// }
|
|
298
345
|
// });
|
|
299
346
|
clients.forEach((client) => {
|
|
@@ -344,6 +391,8 @@ async function start(options) {
|
|
|
344
391
|
};
|
|
345
392
|
|
|
346
393
|
readyThread.ready = false;
|
|
394
|
+
await pendingCliCompile;
|
|
395
|
+
readyThread.used = true;
|
|
347
396
|
readyThread.worker.postMessage({
|
|
348
397
|
mode: "dev-server",
|
|
349
398
|
pathname,
|
|
@@ -485,9 +534,9 @@ async function start(options) {
|
|
|
485
534
|
/<!-- ROOT -->\S*<html lang="en">/m,
|
|
486
535
|
info.rootElement
|
|
487
536
|
);
|
|
537
|
+
setHeaders(res, renderResult.headers);
|
|
488
538
|
res.writeHead(renderResult.statusCode, {
|
|
489
539
|
"Content-Type": "text/html",
|
|
490
|
-
...renderResult.headers,
|
|
491
540
|
});
|
|
492
541
|
res.end(renderedHtml);
|
|
493
542
|
} catch (e) {
|
|
@@ -499,10 +548,8 @@ async function start(options) {
|
|
|
499
548
|
case "api-response": {
|
|
500
549
|
if (renderResult.body.kind === "server-response") {
|
|
501
550
|
const serverResponse = renderResult.body;
|
|
502
|
-
res.
|
|
503
|
-
|
|
504
|
-
serverResponse.headers
|
|
505
|
-
);
|
|
551
|
+
setHeaders(res, serverResponse.headers);
|
|
552
|
+
res.writeHead(serverResponse.statusCode);
|
|
506
553
|
res.end(serverResponse.body);
|
|
507
554
|
} else if (renderResult.body.kind === "static-file") {
|
|
508
555
|
let mimeType = serveStatic.mime.lookup(pathname || "text/html");
|
|
@@ -545,6 +592,16 @@ async function start(options) {
|
|
|
545
592
|
});
|
|
546
593
|
}
|
|
547
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
|
+
|
|
548
605
|
/**
|
|
549
606
|
* @param {string} reviewReportJsonString
|
|
550
607
|
*/
|
|
@@ -590,6 +647,7 @@ async function start(options) {
|
|
|
590
647
|
}
|
|
591
648
|
|
|
592
649
|
function runPendingWork() {
|
|
650
|
+
restartIdleWorkersIfStale();
|
|
593
651
|
const readyThreads = pool.filter((thread) => thread.ready);
|
|
594
652
|
readyThreads.forEach((readyThread) => {
|
|
595
653
|
const startTask = threadReadyQueue.shift();
|
|
@@ -614,6 +672,7 @@ async function start(options) {
|
|
|
614
672
|
workerData: { basePath },
|
|
615
673
|
}),
|
|
616
674
|
ready: false,
|
|
675
|
+
used: false,
|
|
617
676
|
};
|
|
618
677
|
newWorker.worker.once("online", () => {
|
|
619
678
|
newWorker.ready = true;
|
|
@@ -784,4 +843,3 @@ function paramsToObject(entries) {
|
|
|
784
843
|
}
|
|
785
844
|
return result;
|
|
786
845
|
}
|
|
787
|
-
module.exports = { start };
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 */
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
module.exports = { ensureDirSync, deleteIfExists };
|
|
1
|
+
import * as fs from "node:fs";
|
|
3
2
|
|
|
4
|
-
function ensureDirSync(dirpath) {
|
|
3
|
+
export function ensureDirSync(dirpath) {
|
|
5
4
|
try {
|
|
6
5
|
fs.mkdirSync(dirpath, { recursive: true });
|
|
7
6
|
} catch (err) {
|
|
@@ -9,7 +8,7 @@ function ensureDirSync(dirpath) {
|
|
|
9
8
|
}
|
|
10
9
|
}
|
|
11
10
|
|
|
12
|
-
function deleteIfExists(/** @type string */ filePath) {
|
|
11
|
+
export function deleteIfExists(/** @type string */ filePath) {
|
|
13
12
|
if (fs.existsSync(filePath)) {
|
|
14
13
|
fs.unlinkSync(filePath);
|
|
15
14
|
}
|
|
@@ -1,24 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const { restoreColorSafe } = require("./error-formatter");
|
|
1
|
+
import * as globby from "globby";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import { default as mm } from "micromatch";
|
|
4
|
+
import * as routeHelpers from "./route-codegen-helpers.js";
|
|
5
|
+
import { restoreColorSafe } from "./error-formatter.js";
|
|
6
|
+
import { fileURLToPath } from "url";
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
9
|
* @param {string} basePath
|
|
11
10
|
* @param {'browser' | 'cli'} phase
|
|
12
11
|
*/
|
|
13
|
-
async function generateTemplateModuleConnector(basePath, phase) {
|
|
14
|
-
const templates = globby
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
12
|
+
export async function generateTemplateModuleConnector(basePath, phase) {
|
|
13
|
+
const templates = globby
|
|
14
|
+
.globbySync(["app/Route/**/*.elm"], {})
|
|
15
|
+
.map((file) => {
|
|
16
|
+
const captures = mm.capture("app/Route/**/*.elm", file);
|
|
17
|
+
if (captures) {
|
|
18
|
+
return path.join(captures[0], captures[1]).split(path.sep);
|
|
19
|
+
} else {
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
});
|
|
22
23
|
if (templates.length <= 0) {
|
|
23
24
|
throw {
|
|
24
25
|
path: "",
|
|
@@ -63,10 +64,12 @@ async function generateTemplateModuleConnector(basePath, phase) {
|
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
async function runElmCodegenCli(templates, basePath, phase) {
|
|
66
|
-
const
|
|
67
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
68
|
+
const __dirname = path.dirname(__filename);
|
|
69
|
+
const filePath = path.join(__dirname, `../../codegen/elm-pages-codegen.cjs`);
|
|
67
70
|
|
|
68
|
-
const promise = new Promise((resolve, reject) => {
|
|
69
|
-
const elmPagesCodegen =
|
|
71
|
+
const promise = new Promise(async (resolve, reject) => {
|
|
72
|
+
const elmPagesCodegen = (await import(filePath)).default.Elm.Generate;
|
|
70
73
|
|
|
71
74
|
const app = elmPagesCodegen.init({
|
|
72
75
|
flags: { templates: templates, basePath, phase },
|
|
@@ -91,7 +94,7 @@ async function runElmCodegenCli(templates, basePath, phase) {
|
|
|
91
94
|
* @param {string[][]} templates
|
|
92
95
|
* @returns
|
|
93
96
|
*/
|
|
94
|
-
function sortTemplates(templates) {
|
|
97
|
+
export function sortTemplates(templates) {
|
|
95
98
|
return templates.sort((first, second) => {
|
|
96
99
|
const a = sortScore(first);
|
|
97
100
|
const b = sortScore(second);
|
|
@@ -186,7 +189,6 @@ function fetcherModule(name) {
|
|
|
186
189
|
|
|
187
190
|
import Bytes exposing (Bytes)
|
|
188
191
|
import Bytes.Decode
|
|
189
|
-
import FormDecoder
|
|
190
192
|
import Http
|
|
191
193
|
import Pages.Fetcher
|
|
192
194
|
import Route.${moduleName}
|
|
@@ -230,5 +232,3 @@ submit toMsg options =
|
|
|
230
232
|
function camelToKebab(input) {
|
|
231
233
|
return input.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
|
|
232
234
|
}
|
|
233
|
-
|
|
234
|
-
module.exports = { generateTemplateModuleConnector, sortTemplates };
|