elm-pages 3.0.0-beta.3 → 3.0.0-beta.31
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 +10 -1
- package/codegen/{elm-pages-codegen.js → elm-pages-codegen.cjs} +2864 -2589
- 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 +1447 -342
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Runner.elm.js +16458 -13724
- 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 +1447 -342
- package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +24542 -21748
- 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 +113 -107
- package/generator/src/SharedTemplate.elm +3 -2
- package/generator/src/SiteConfig.elm +3 -2
- package/generator/src/basepath-middleware.js +3 -3
- package/generator/src/build.js +125 -88
- package/generator/src/cli.js +273 -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 +39 -0
- package/generator/src/copy-dir.js +2 -2
- package/generator/src/dev-server.js +150 -133
- 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 -22
- package/generator/src/init.js +9 -8
- package/generator/src/pre-render-html.js +39 -28
- package/generator/src/render-test.js +109 -0
- package/generator/src/render-worker.js +25 -28
- package/generator/src/render.js +320 -142
- package/generator/src/request-cache.js +252 -163
- package/generator/src/resolve-elm-module.js +63 -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 +12 -7
- package/generator/src/vite-utils.js +77 -0
- package/generator/static-code/hmr.js +79 -13
- package/generator/template/app/Api.elm +6 -5
- package/generator/template/app/Effect.elm +123 -0
- package/generator/template/app/ErrorPage.elm +37 -6
- package/generator/template/app/Route/Index.elm +17 -10
- package/generator/template/app/Shared.elm +24 -47
- package/generator/template/app/Site.elm +19 -6
- package/generator/template/app/View.elm +1 -8
- package/generator/template/elm-tooling.json +0 -3
- package/generator/template/elm.json +32 -24
- package/generator/template/package.json +10 -4
- package/package.json +29 -27
- package/src/ApiRoute.elm +199 -61
- package/src/BackendTask/Custom.elm +325 -0
- package/src/BackendTask/Env.elm +90 -0
- package/src/{DataSource → BackendTask}/File.elm +128 -43
- package/src/{DataSource → BackendTask}/Glob.elm +136 -125
- package/src/BackendTask/Http.elm +673 -0
- package/src/{DataSource → BackendTask}/Internal/Glob.elm +1 -1
- package/src/BackendTask/Internal/Request.elm +28 -0
- package/src/BackendTask/Random.elm +79 -0
- package/src/BackendTask/Time.elm +47 -0
- package/src/BackendTask.elm +537 -0
- package/src/FatalError.elm +89 -0
- package/src/Form/Field.elm +21 -9
- package/src/Form/FieldView.elm +94 -14
- package/src/Form.elm +275 -400
- package/src/Head.elm +237 -7
- package/src/HtmlPrinter.elm +7 -3
- package/src/Internal/ApiRoute.elm +7 -5
- package/src/PageServerResponse.elm +6 -1
- package/src/Pages/FormState.elm +6 -5
- package/src/Pages/GeneratorProgramConfig.elm +15 -0
- package/src/Pages/Internal/FatalError.elm +5 -0
- package/src/Pages/Internal/Form.elm +21 -1
- package/src/Pages/{Msg.elm → Internal/Msg.elm} +26 -16
- package/src/Pages/Internal/Platform/Cli.elm +598 -763
- package/src/Pages/Internal/Platform/CompatibilityKey.elm +6 -0
- package/src/Pages/Internal/Platform/Effect.elm +1 -2
- package/src/Pages/Internal/Platform/GeneratorApplication.elm +373 -0
- package/src/Pages/Internal/Platform/StaticResponses.elm +73 -270
- package/src/Pages/Internal/Platform/ToJsPayload.elm +4 -7
- package/src/Pages/Internal/Platform.elm +216 -102
- package/src/Pages/Internal/Script.elm +17 -0
- package/src/Pages/Internal/StaticHttpBody.elm +35 -1
- package/src/Pages/Manifest.elm +29 -4
- package/src/Pages/PageUrl.elm +23 -9
- package/src/Pages/ProgramConfig.elm +14 -10
- package/src/Pages/Script.elm +109 -0
- package/src/Pages/SiteConfig.elm +3 -2
- package/src/Pages/StaticHttp/Request.elm +2 -2
- package/src/Pages/StaticHttpRequest.elm +23 -98
- package/src/PagesMsg.elm +92 -0
- package/src/Path.elm +16 -19
- package/src/QueryParams.elm +21 -172
- package/src/RequestsAndPending.elm +8 -19
- package/src/Result/Extra.elm +26 -0
- package/src/Scaffold/Form.elm +560 -0
- package/src/Scaffold/Route.elm +1388 -0
- package/src/Server/Request.elm +43 -37
- package/src/Server/Session.elm +62 -42
- package/src/Server/SetCookie.elm +12 -4
- package/src/Test/Html/Internal/ElmHtml/ToString.elm +8 -9
- 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 -538
- package/src/Pages/Generate.elm +0 -800
package/generator/src/render.js
CHANGED
|
@@ -1,67 +1,220 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import { default as mm } from "micromatch";
|
|
5
|
+
import { default as matter } from "gray-matter";
|
|
6
|
+
import * as globby from "globby";
|
|
7
|
+
import * as fsPromises from "node:fs/promises";
|
|
8
|
+
import * as preRenderHtml from "./pre-render-html.js";
|
|
9
|
+
import { lookupOrPerform } from "./request-cache.js";
|
|
10
|
+
import * as kleur from "kleur/colors";
|
|
11
|
+
import * as cookie from "cookie-signature";
|
|
12
|
+
import { compatibilityKey } from "./compatibility-key.js";
|
|
13
|
+
import * as fs from "node:fs";
|
|
14
|
+
import * as crypto from "node:crypto";
|
|
15
|
+
import { restoreColorSafe } from "./error-formatter.js";
|
|
13
16
|
|
|
14
17
|
process.on("unhandledRejection", (error) => {
|
|
15
18
|
console.error(error);
|
|
16
19
|
});
|
|
17
20
|
let foundErrors;
|
|
18
|
-
let pendingDataSourceResponses;
|
|
19
|
-
let pendingDataSourceCount;
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
22
|
+
/**
|
|
23
|
+
*
|
|
24
|
+
* @param {string} basePath
|
|
25
|
+
* @param {Object} elmModule
|
|
26
|
+
* @param {string} path
|
|
27
|
+
* @param {{ method: string; hostname: string; query: Record<string, string | undefined>; headers: Record<string, string>; host: string; pathname: string; port: number | null; protocol: string; rawUrl: string; }} request
|
|
28
|
+
* @param {(pattern: string) => void} addBackendTaskWatcher
|
|
29
|
+
* @param {boolean} hasFsAccess
|
|
30
|
+
* @returns
|
|
31
|
+
*/
|
|
32
|
+
export async function render(
|
|
33
|
+
portsFile,
|
|
34
|
+
basePath,
|
|
35
|
+
elmModule,
|
|
36
|
+
mode,
|
|
37
|
+
path,
|
|
38
|
+
request,
|
|
39
|
+
addBackendTaskWatcher,
|
|
40
|
+
hasFsAccess
|
|
41
|
+
) {
|
|
42
|
+
// const { fs, resetInMemoryFs } = require("./request-cache-fs.js")(hasFsAccess);
|
|
43
|
+
// resetInMemoryFs();
|
|
44
|
+
foundErrors = false;
|
|
45
|
+
// since init/update are never called in pre-renders, and BackendTask.Http is called using pure NodeJS HTTP fetching
|
|
46
|
+
// we can provide a fake HTTP instead of xhr2 (which is otherwise needed for Elm HTTP requests from Node)
|
|
47
|
+
global.XMLHttpRequest = {};
|
|
48
|
+
const result = await runElmApp(
|
|
33
49
|
portsFile,
|
|
34
50
|
basePath,
|
|
35
51
|
elmModule,
|
|
36
52
|
mode,
|
|
37
53
|
path,
|
|
38
54
|
request,
|
|
39
|
-
|
|
55
|
+
addBackendTaskWatcher,
|
|
40
56
|
hasFsAccess
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
57
|
+
);
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @param {Object} elmModule
|
|
63
|
+
* @returns
|
|
64
|
+
* @param {string[]} cliOptions
|
|
65
|
+
* @param {any} portsFile
|
|
66
|
+
* @param {string} scriptModuleName
|
|
67
|
+
*/
|
|
68
|
+
export async function runGenerator(
|
|
69
|
+
cliOptions,
|
|
70
|
+
portsFile,
|
|
71
|
+
elmModule,
|
|
72
|
+
scriptModuleName
|
|
73
|
+
) {
|
|
74
|
+
global.isRunningGenerator = true;
|
|
75
|
+
// const { fs, resetInMemoryFs } = require("./request-cache-fs.js")(true);
|
|
76
|
+
// resetInMemoryFs();
|
|
77
|
+
foundErrors = false;
|
|
78
|
+
// since init/update are never called in pre-renders, and BackendTask.Http is called using pure NodeJS HTTP fetching
|
|
79
|
+
// we can provide a fake HTTP instead of xhr2 (which is otherwise needed for Elm HTTP requests from Node)
|
|
80
|
+
global.XMLHttpRequest = {};
|
|
81
|
+
try {
|
|
82
|
+
const result = await runGeneratorAppHelp(
|
|
83
|
+
cliOptions,
|
|
53
84
|
portsFile,
|
|
54
|
-
|
|
85
|
+
"",
|
|
55
86
|
elmModule,
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
fs,
|
|
61
|
-
hasFsAccess
|
|
87
|
+
scriptModuleName,
|
|
88
|
+
"production",
|
|
89
|
+
"",
|
|
90
|
+
true
|
|
62
91
|
);
|
|
63
92
|
return result;
|
|
64
|
-
}
|
|
93
|
+
} catch (error) {
|
|
94
|
+
console.log(restoreColorSafe(error));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* @param {string} basePath
|
|
99
|
+
* @param {Object} elmModule
|
|
100
|
+
* @param {string} pagePath
|
|
101
|
+
* @param {string} mode
|
|
102
|
+
* @returns {Promise<({is404: boolean;} & ({kind: 'json';contentJson: string;} | {kind: 'html';htmlString: string;} | {kind: 'api-response';body: string;}))>}
|
|
103
|
+
* @param {string[]} cliOptions
|
|
104
|
+
* @param {any} portsFile
|
|
105
|
+
* @param {typeof import("fs") | import("memfs").IFs} fs
|
|
106
|
+
* @param {boolean} hasFsAccess
|
|
107
|
+
* @param {string} scriptModuleName
|
|
108
|
+
*/
|
|
109
|
+
function runGeneratorAppHelp(
|
|
110
|
+
cliOptions,
|
|
111
|
+
portsFile,
|
|
112
|
+
basePath,
|
|
113
|
+
elmModule,
|
|
114
|
+
scriptModuleName,
|
|
115
|
+
mode,
|
|
116
|
+
pagePath,
|
|
117
|
+
hasFsAccess
|
|
118
|
+
) {
|
|
119
|
+
const isDevServer = mode !== "build";
|
|
120
|
+
let patternsToWatch = new Set();
|
|
121
|
+
let app = null;
|
|
122
|
+
let killApp;
|
|
123
|
+
return new Promise((resolve, reject) => {
|
|
124
|
+
const isBytes = pagePath.match(/content\.dat\/?$/);
|
|
125
|
+
|
|
126
|
+
app = elmModule.Elm.Main.init({
|
|
127
|
+
flags: {
|
|
128
|
+
compatibilityKey,
|
|
129
|
+
argv: ["", `elm-pages run ${scriptModuleName}`, ...cliOptions],
|
|
130
|
+
versionMessage: "1.2.3",
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
killApp = () => {
|
|
135
|
+
app.ports.toJsPort.unsubscribe(portHandler);
|
|
136
|
+
app.die();
|
|
137
|
+
app = null;
|
|
138
|
+
// delete require.cache[require.resolve(compiledElmPath)];
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
async function portHandler(/** @type { FromElm } */ newThing) {
|
|
142
|
+
let fromElm;
|
|
143
|
+
let contentDatPayload;
|
|
144
|
+
|
|
145
|
+
fromElm = newThing;
|
|
146
|
+
if (fromElm.command === "log") {
|
|
147
|
+
console.log(fromElm.value);
|
|
148
|
+
} else if (fromElm.tag === "ApiResponse") {
|
|
149
|
+
// Finished successfully
|
|
150
|
+
process.exit(0);
|
|
151
|
+
} else if (fromElm.tag === "PageProgress") {
|
|
152
|
+
const args = fromElm.args[0];
|
|
153
|
+
|
|
154
|
+
if (isBytes) {
|
|
155
|
+
resolve({
|
|
156
|
+
kind: "bytes",
|
|
157
|
+
is404: false,
|
|
158
|
+
contentJson: JSON.stringify({
|
|
159
|
+
staticData: args.contentJson,
|
|
160
|
+
is404: false,
|
|
161
|
+
}),
|
|
162
|
+
statusCode: args.statusCode,
|
|
163
|
+
headers: args.headers,
|
|
164
|
+
contentDatPayload,
|
|
165
|
+
});
|
|
166
|
+
} else {
|
|
167
|
+
resolve(
|
|
168
|
+
outputString(basePath, fromElm, isDevServer, contentDatPayload)
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
} else if (fromElm.tag === "DoHttp") {
|
|
172
|
+
app.ports.gotBatchSub.send(
|
|
173
|
+
Object.fromEntries(
|
|
174
|
+
await Promise.all(
|
|
175
|
+
fromElm.args[0].map(([requestHash, requestToPerform]) => {
|
|
176
|
+
if (
|
|
177
|
+
requestToPerform.url !== "elm-pages-internal://port" &&
|
|
178
|
+
requestToPerform.url.startsWith("elm-pages-internal://")
|
|
179
|
+
) {
|
|
180
|
+
return runInternalJob(
|
|
181
|
+
requestHash,
|
|
182
|
+
app,
|
|
183
|
+
mode,
|
|
184
|
+
requestToPerform,
|
|
185
|
+
hasFsAccess,
|
|
186
|
+
patternsToWatch
|
|
187
|
+
);
|
|
188
|
+
} else {
|
|
189
|
+
return runHttpJob(
|
|
190
|
+
requestHash,
|
|
191
|
+
portsFile,
|
|
192
|
+
app,
|
|
193
|
+
mode,
|
|
194
|
+
requestToPerform,
|
|
195
|
+
hasFsAccess,
|
|
196
|
+
requestToPerform
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
})
|
|
200
|
+
)
|
|
201
|
+
)
|
|
202
|
+
);
|
|
203
|
+
} else if (fromElm.tag === "Errors") {
|
|
204
|
+
foundErrors = true;
|
|
205
|
+
reject(fromElm.args[0].errorsJson);
|
|
206
|
+
} else {
|
|
207
|
+
console.log(fromElm);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
app.ports.toJsPort.subscribe(portHandler);
|
|
211
|
+
}).finally(() => {
|
|
212
|
+
try {
|
|
213
|
+
killApp();
|
|
214
|
+
killApp = null;
|
|
215
|
+
} catch (error) {}
|
|
216
|
+
});
|
|
217
|
+
}
|
|
65
218
|
|
|
66
219
|
/**
|
|
67
220
|
* @param {string} basePath
|
|
@@ -69,7 +222,7 @@ module.exports =
|
|
|
69
222
|
* @param {string} pagePath
|
|
70
223
|
* @param {string} mode
|
|
71
224
|
* @param {{ method: string; hostname: string; query: string; headers: Object; host: string; pathname: string; port: string; protocol: string; rawUrl: string; }} request
|
|
72
|
-
* @param {(pattern: string) => void}
|
|
225
|
+
* @param {(pattern: string) => void} addBackendTaskWatcher
|
|
73
226
|
* @returns {Promise<({is404: boolean} & ( { kind: 'json'; contentJson: string} | { kind: 'html'; htmlString: string } | { kind: 'api-response'; body: string; }) )>}
|
|
74
227
|
*/
|
|
75
228
|
function runElmApp(
|
|
@@ -79,8 +232,7 @@ function runElmApp(
|
|
|
79
232
|
mode,
|
|
80
233
|
pagePath,
|
|
81
234
|
request,
|
|
82
|
-
|
|
83
|
-
fs,
|
|
235
|
+
addBackendTaskWatcher,
|
|
84
236
|
hasFsAccess
|
|
85
237
|
) {
|
|
86
238
|
const isDevServer = mode !== "build";
|
|
@@ -94,10 +246,10 @@ function runElmApp(
|
|
|
94
246
|
.replace(/content\.dat\/?$/, "");
|
|
95
247
|
|
|
96
248
|
const modifiedRequest = { ...request, path: route };
|
|
97
|
-
// console.log("StaticHttp cache keys", Object.keys(global.staticHttpCache));
|
|
98
249
|
app = elmModule.Elm.Main.init({
|
|
99
250
|
flags: {
|
|
100
251
|
mode,
|
|
252
|
+
compatibilityKey,
|
|
101
253
|
request: {
|
|
102
254
|
payload: modifiedRequest,
|
|
103
255
|
kind: "single-page",
|
|
@@ -127,9 +279,6 @@ function runElmApp(
|
|
|
127
279
|
console.log(fromElm.value);
|
|
128
280
|
} else if (fromElm.tag === "ApiResponse") {
|
|
129
281
|
const args = fromElm.args[0];
|
|
130
|
-
if (mode === "build") {
|
|
131
|
-
global.staticHttpCache = args.staticHttpCache;
|
|
132
|
-
}
|
|
133
282
|
|
|
134
283
|
resolve({
|
|
135
284
|
kind: "api-response",
|
|
@@ -139,10 +288,6 @@ function runElmApp(
|
|
|
139
288
|
});
|
|
140
289
|
} else if (fromElm.tag === "PageProgress") {
|
|
141
290
|
const args = fromElm.args[0];
|
|
142
|
-
if (mode === "build") {
|
|
143
|
-
global.staticHttpCache = args.staticHttpCache;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
291
|
if (isBytes) {
|
|
147
292
|
resolve({
|
|
148
293
|
kind: "bytes",
|
|
@@ -161,30 +306,37 @@ function runElmApp(
|
|
|
161
306
|
);
|
|
162
307
|
}
|
|
163
308
|
} else if (fromElm.tag === "DoHttp") {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
309
|
+
app.ports.gotBatchSub.send(
|
|
310
|
+
Object.fromEntries(
|
|
311
|
+
await Promise.all(
|
|
312
|
+
fromElm.args[0].map(([requestHash, requestToPerform]) => {
|
|
313
|
+
if (
|
|
314
|
+
requestToPerform.url !== "elm-pages-internal://port" &&
|
|
315
|
+
requestToPerform.url.startsWith("elm-pages-internal://")
|
|
316
|
+
) {
|
|
317
|
+
return runInternalJob(
|
|
318
|
+
requestHash,
|
|
319
|
+
app,
|
|
320
|
+
mode,
|
|
321
|
+
requestToPerform,
|
|
322
|
+
hasFsAccess,
|
|
323
|
+
patternsToWatch
|
|
324
|
+
);
|
|
325
|
+
} else {
|
|
326
|
+
return runHttpJob(
|
|
327
|
+
requestHash,
|
|
328
|
+
portsFile,
|
|
329
|
+
app,
|
|
330
|
+
mode,
|
|
331
|
+
requestToPerform,
|
|
332
|
+
hasFsAccess,
|
|
333
|
+
requestToPerform
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
})
|
|
337
|
+
)
|
|
338
|
+
)
|
|
339
|
+
);
|
|
188
340
|
} else if (fromElm.tag === "Errors") {
|
|
189
341
|
foundErrors = true;
|
|
190
342
|
reject(fromElm.args[0].errorsJson);
|
|
@@ -195,7 +347,7 @@ function runElmApp(
|
|
|
195
347
|
app.ports.toJsPort.subscribe(portHandler);
|
|
196
348
|
app.ports.sendPageData.subscribe(portHandler);
|
|
197
349
|
}).finally(() => {
|
|
198
|
-
|
|
350
|
+
addBackendTaskWatcher(patternsToWatch);
|
|
199
351
|
try {
|
|
200
352
|
killApp();
|
|
201
353
|
killApp = null;
|
|
@@ -244,17 +396,16 @@ async function outputString(
|
|
|
244
396
|
/** @typedef { { head: any[]; errors: any[]; contentJson: any[]; html: string; route: string; title: string; } } Arg */
|
|
245
397
|
|
|
246
398
|
async function runHttpJob(
|
|
399
|
+
requestHash,
|
|
247
400
|
portsFile,
|
|
248
401
|
app,
|
|
249
402
|
mode,
|
|
250
403
|
requestToPerform,
|
|
251
|
-
fs,
|
|
252
404
|
hasFsAccess,
|
|
253
405
|
useCache
|
|
254
406
|
) {
|
|
255
|
-
pendingDataSourceCount += 1;
|
|
256
407
|
try {
|
|
257
|
-
const
|
|
408
|
+
const lookupResponse = await lookupOrPerform(
|
|
258
409
|
portsFile,
|
|
259
410
|
mode,
|
|
260
411
|
requestToPerform,
|
|
@@ -262,17 +413,31 @@ async function runHttpJob(
|
|
|
262
413
|
useCache
|
|
263
414
|
);
|
|
264
415
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
416
|
+
if (lookupResponse.kind === "cache-response-path") {
|
|
417
|
+
const responseFilePath = lookupResponse.value;
|
|
418
|
+
return [
|
|
419
|
+
requestHash,
|
|
420
|
+
{
|
|
421
|
+
request: requestToPerform,
|
|
422
|
+
response: JSON.parse(
|
|
423
|
+
(await fs.promises.readFile(responseFilePath, "utf8")).toString()
|
|
424
|
+
),
|
|
425
|
+
},
|
|
426
|
+
];
|
|
427
|
+
} else if (lookupResponse.kind === "response-json") {
|
|
428
|
+
return [
|
|
429
|
+
requestHash,
|
|
430
|
+
{
|
|
431
|
+
request: requestToPerform,
|
|
432
|
+
response: lookupResponse.value,
|
|
433
|
+
},
|
|
434
|
+
];
|
|
435
|
+
} else {
|
|
436
|
+
throw `Unexpected kind ${lookupResponse}`;
|
|
437
|
+
}
|
|
271
438
|
} catch (error) {
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
pendingDataSourceCount -= 1;
|
|
275
|
-
flushIfDone(app);
|
|
439
|
+
console.log("@@@ERROR", error);
|
|
440
|
+
// sendError(app, error);
|
|
276
441
|
}
|
|
277
442
|
}
|
|
278
443
|
|
|
@@ -290,46 +455,54 @@ function jsonResponse(request, json) {
|
|
|
290
455
|
}
|
|
291
456
|
|
|
292
457
|
async function runInternalJob(
|
|
458
|
+
requestHash,
|
|
293
459
|
app,
|
|
294
460
|
mode,
|
|
295
461
|
requestToPerform,
|
|
296
|
-
fs,
|
|
297
462
|
hasFsAccess,
|
|
298
463
|
patternsToWatch
|
|
299
464
|
) {
|
|
300
465
|
try {
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
if (requestToPerform.url === "elm-pages-internal://read-file") {
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
466
|
+
if (requestToPerform.url === "elm-pages-internal://log") {
|
|
467
|
+
return [requestHash, await runLogJob(requestToPerform)];
|
|
468
|
+
} else if (requestToPerform.url === "elm-pages-internal://read-file") {
|
|
469
|
+
return [
|
|
470
|
+
requestHash,
|
|
471
|
+
await readFileJobNew(requestToPerform, patternsToWatch),
|
|
472
|
+
];
|
|
307
473
|
} else if (requestToPerform.url === "elm-pages-internal://glob") {
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
474
|
+
return [requestHash, await runGlobNew(requestToPerform, patternsToWatch)];
|
|
475
|
+
} else if (requestToPerform.url === "elm-pages-internal://randomSeed") {
|
|
476
|
+
return [
|
|
477
|
+
requestHash,
|
|
478
|
+
jsonResponse(
|
|
479
|
+
requestToPerform,
|
|
480
|
+
crypto.getRandomValues(new Uint32Array(1))[0]
|
|
481
|
+
),
|
|
482
|
+
];
|
|
483
|
+
} else if (requestToPerform.url === "elm-pages-internal://now") {
|
|
484
|
+
return [requestHash, jsonResponse(requestToPerform, Date.now())];
|
|
311
485
|
} else if (requestToPerform.url === "elm-pages-internal://env") {
|
|
312
|
-
|
|
313
|
-
await runEnvJob(requestToPerform, patternsToWatch)
|
|
314
|
-
);
|
|
486
|
+
return [requestHash, await runEnvJob(requestToPerform, patternsToWatch)];
|
|
315
487
|
} else if (requestToPerform.url === "elm-pages-internal://encrypt") {
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
488
|
+
return [
|
|
489
|
+
requestHash,
|
|
490
|
+
await runEncryptJob(requestToPerform, patternsToWatch),
|
|
491
|
+
];
|
|
319
492
|
} else if (requestToPerform.url === "elm-pages-internal://decrypt") {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
493
|
+
return [
|
|
494
|
+
requestHash,
|
|
495
|
+
await runDecryptJob(requestToPerform, patternsToWatch),
|
|
496
|
+
];
|
|
497
|
+
} else if (requestToPerform.url === "elm-pages-internal://write-file") {
|
|
498
|
+
return [requestHash, await runWriteFileJob(requestToPerform)];
|
|
323
499
|
} else {
|
|
324
|
-
throw `Unexpected internal
|
|
500
|
+
throw `Unexpected internal BackendTask request format: ${kleur.yellow(
|
|
325
501
|
JSON.stringify(2, null, requestToPerform)
|
|
326
502
|
)}`;
|
|
327
503
|
}
|
|
328
504
|
} catch (error) {
|
|
329
505
|
sendError(app, error);
|
|
330
|
-
} finally {
|
|
331
|
-
pendingDataSourceCount -= 1;
|
|
332
|
-
flushIfDone(app);
|
|
333
506
|
}
|
|
334
507
|
}
|
|
335
508
|
|
|
@@ -344,6 +517,7 @@ async function readFileJobNew(req, patternsToWatch) {
|
|
|
344
517
|
path.join(process.env.LAMBDA_TASK_ROOT || process.cwd(), filePath)
|
|
345
518
|
)
|
|
346
519
|
).toString();
|
|
520
|
+
// TODO does this throw an error if there is invalid frontmatter?
|
|
347
521
|
const parsedFile = matter(fileContents);
|
|
348
522
|
|
|
349
523
|
return jsonResponse(req, {
|
|
@@ -352,10 +526,24 @@ async function readFileJobNew(req, patternsToWatch) {
|
|
|
352
526
|
rawFile: fileContents,
|
|
353
527
|
});
|
|
354
528
|
} catch (error) {
|
|
529
|
+
return jsonResponse(req, {
|
|
530
|
+
errorCode: error.code,
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
async function runWriteFileJob(req) {
|
|
535
|
+
const data = req.body.args[0];
|
|
536
|
+
try {
|
|
537
|
+
const fullPathToWrite = path.join(process.cwd(), data.path);
|
|
538
|
+
await fsPromises.mkdir(path.dirname(fullPathToWrite), { recursive: true });
|
|
539
|
+
await fsPromises.writeFile(fullPathToWrite, data.body);
|
|
540
|
+
return jsonResponse(req, null);
|
|
541
|
+
} catch (error) {
|
|
542
|
+
console.trace(error);
|
|
355
543
|
throw {
|
|
356
|
-
title: "
|
|
357
|
-
message: `
|
|
358
|
-
|
|
544
|
+
title: "BackendTask Error",
|
|
545
|
+
message: `BackendTask.Generator.writeFile failed for file path: ${kleur.yellow(
|
|
546
|
+
data.path
|
|
359
547
|
)}\n${kleur.red(error.toString())}`,
|
|
360
548
|
};
|
|
361
549
|
}
|
|
@@ -364,7 +552,7 @@ async function readFileJobNew(req, patternsToWatch) {
|
|
|
364
552
|
async function runGlobNew(req, patternsToWatch) {
|
|
365
553
|
try {
|
|
366
554
|
const { pattern, options } = req.body.args[0];
|
|
367
|
-
const matchedPaths = await globby(pattern, options);
|
|
555
|
+
const matchedPaths = await globby.globby(pattern, options);
|
|
368
556
|
patternsToWatch.add(pattern);
|
|
369
557
|
|
|
370
558
|
return jsonResponse(
|
|
@@ -382,6 +570,15 @@ async function runGlobNew(req, patternsToWatch) {
|
|
|
382
570
|
}
|
|
383
571
|
}
|
|
384
572
|
|
|
573
|
+
async function runLogJob(req) {
|
|
574
|
+
try {
|
|
575
|
+
console.log(req.body.args[0].message);
|
|
576
|
+
return jsonResponse(req, null);
|
|
577
|
+
} catch (e) {
|
|
578
|
+
console.log(`Error performing env '${JSON.stringify(req.body)}'`);
|
|
579
|
+
throw e;
|
|
580
|
+
}
|
|
581
|
+
}
|
|
385
582
|
async function runEnvJob(req, patternsToWatch) {
|
|
386
583
|
try {
|
|
387
584
|
const expectedEnv = req.body.args[0];
|
|
@@ -402,7 +599,7 @@ async function runEncryptJob(req, patternsToWatch) {
|
|
|
402
599
|
);
|
|
403
600
|
} catch (e) {
|
|
404
601
|
throw {
|
|
405
|
-
title: "
|
|
602
|
+
title: "BackendTask Encrypt Error",
|
|
406
603
|
message:
|
|
407
604
|
e.toString() + e.stack + "\n\n" + JSON.stringify(rawRequest, null, 2),
|
|
408
605
|
};
|
|
@@ -419,32 +616,13 @@ async function runDecryptJob(req, patternsToWatch) {
|
|
|
419
616
|
return jsonResponse(req, JSON.parse(signed || "null"));
|
|
420
617
|
} catch (e) {
|
|
421
618
|
throw {
|
|
422
|
-
title: "
|
|
619
|
+
title: "BackendTask Decrypt Error",
|
|
423
620
|
message:
|
|
424
621
|
e.toString() + e.stack + "\n\n" + JSON.stringify(rawRequest, null, 2),
|
|
425
622
|
};
|
|
426
623
|
}
|
|
427
624
|
}
|
|
428
625
|
|
|
429
|
-
function flushIfDone(app) {
|
|
430
|
-
if (foundErrors) {
|
|
431
|
-
pendingDataSourceResponses = [];
|
|
432
|
-
} else if (pendingDataSourceCount === 0) {
|
|
433
|
-
// console.log(
|
|
434
|
-
// `Flushing ${pendingDataSourceResponses.length} items in ${timeUntilThreshold}ms`
|
|
435
|
-
// );
|
|
436
|
-
|
|
437
|
-
flushQueue(app);
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
function flushQueue(app) {
|
|
442
|
-
const temp = pendingDataSourceResponses;
|
|
443
|
-
pendingDataSourceResponses = [];
|
|
444
|
-
// console.log("@@@ FLUSHING", temp.length);
|
|
445
|
-
app.ports.gotBatchSub.send(temp);
|
|
446
|
-
}
|
|
447
|
-
|
|
448
626
|
/**
|
|
449
627
|
* @param {{ ports: { fromJsPort: { send: (arg0: { tag: string; data: any; }) => void; }; }; }} app
|
|
450
628
|
* @param {{ message: string; title: string; }} error
|