elm-pages 3.0.0-beta.3 → 3.0.0-beta.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +1327 -122
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Runner.elm.js +15295 -13271
- 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 +8 -6
- 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/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 +1327 -122
- package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +14621 -12637
- 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 +8 -8
- 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 +123 -87
- package/generator/src/cli.js +256 -77
- package/generator/src/codegen.js +29 -27
- package/generator/src/compatibility-key.js +3 -0
- package/generator/src/compile-elm.js +25 -25
- 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 +322 -142
- package/generator/src/request-cache.js +252 -163
- package/generator/src/rewrite-client-elm-json.js +5 -5
- package/generator/src/rewrite-elm-json.js +7 -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 +34 -25
- package/generator/template/package.json +10 -4
- package/package.json +23 -22
- 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 +507 -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 +215 -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 +484 -0
- package/src/Scaffold/Route.elm +1376 -0
- package/src/Server/Request.elm +43 -37
- package/src/Server/Session.elm +34 -34
- package/src/Server/SetCookie.elm +1 -1
- 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,222 @@
|
|
|
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.ports.sendPageData.unsubscribe(portHandler);
|
|
137
|
+
app.die();
|
|
138
|
+
app = null;
|
|
139
|
+
// delete require.cache[require.resolve(compiledElmPath)];
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
async function portHandler(/** @type { FromElm } */ newThing) {
|
|
143
|
+
let fromElm;
|
|
144
|
+
let contentDatPayload;
|
|
145
|
+
|
|
146
|
+
fromElm = newThing;
|
|
147
|
+
if (fromElm.command === "log") {
|
|
148
|
+
console.log(fromElm.value);
|
|
149
|
+
} else if (fromElm.tag === "ApiResponse") {
|
|
150
|
+
// Finished successfully
|
|
151
|
+
process.exit(0);
|
|
152
|
+
} else if (fromElm.tag === "PageProgress") {
|
|
153
|
+
const args = fromElm.args[0];
|
|
154
|
+
|
|
155
|
+
if (isBytes) {
|
|
156
|
+
resolve({
|
|
157
|
+
kind: "bytes",
|
|
158
|
+
is404: false,
|
|
159
|
+
contentJson: JSON.stringify({
|
|
160
|
+
staticData: args.contentJson,
|
|
161
|
+
is404: false,
|
|
162
|
+
}),
|
|
163
|
+
statusCode: args.statusCode,
|
|
164
|
+
headers: args.headers,
|
|
165
|
+
contentDatPayload,
|
|
166
|
+
});
|
|
167
|
+
} else {
|
|
168
|
+
resolve(
|
|
169
|
+
outputString(basePath, fromElm, isDevServer, contentDatPayload)
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
} else if (fromElm.tag === "DoHttp") {
|
|
173
|
+
app.ports.gotBatchSub.send(
|
|
174
|
+
Object.fromEntries(
|
|
175
|
+
await Promise.all(
|
|
176
|
+
fromElm.args[0].map(([requestHash, requestToPerform]) => {
|
|
177
|
+
if (
|
|
178
|
+
requestToPerform.url !== "elm-pages-internal://port" &&
|
|
179
|
+
requestToPerform.url.startsWith("elm-pages-internal://")
|
|
180
|
+
) {
|
|
181
|
+
return runInternalJob(
|
|
182
|
+
requestHash,
|
|
183
|
+
app,
|
|
184
|
+
mode,
|
|
185
|
+
requestToPerform,
|
|
186
|
+
hasFsAccess,
|
|
187
|
+
patternsToWatch
|
|
188
|
+
);
|
|
189
|
+
} else {
|
|
190
|
+
return runHttpJob(
|
|
191
|
+
requestHash,
|
|
192
|
+
portsFile,
|
|
193
|
+
app,
|
|
194
|
+
mode,
|
|
195
|
+
requestToPerform,
|
|
196
|
+
hasFsAccess,
|
|
197
|
+
requestToPerform
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
})
|
|
201
|
+
)
|
|
202
|
+
)
|
|
203
|
+
);
|
|
204
|
+
} else if (fromElm.tag === "Errors") {
|
|
205
|
+
foundErrors = true;
|
|
206
|
+
reject(fromElm.args[0].errorsJson);
|
|
207
|
+
} else {
|
|
208
|
+
console.log(fromElm);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
app.ports.toJsPort.subscribe(portHandler);
|
|
212
|
+
app.ports.sendPageData.subscribe(portHandler);
|
|
213
|
+
}).finally(() => {
|
|
214
|
+
try {
|
|
215
|
+
killApp();
|
|
216
|
+
killApp = null;
|
|
217
|
+
} catch (error) {}
|
|
218
|
+
});
|
|
219
|
+
}
|
|
65
220
|
|
|
66
221
|
/**
|
|
67
222
|
* @param {string} basePath
|
|
@@ -69,7 +224,7 @@ module.exports =
|
|
|
69
224
|
* @param {string} pagePath
|
|
70
225
|
* @param {string} mode
|
|
71
226
|
* @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}
|
|
227
|
+
* @param {(pattern: string) => void} addBackendTaskWatcher
|
|
73
228
|
* @returns {Promise<({is404: boolean} & ( { kind: 'json'; contentJson: string} | { kind: 'html'; htmlString: string } | { kind: 'api-response'; body: string; }) )>}
|
|
74
229
|
*/
|
|
75
230
|
function runElmApp(
|
|
@@ -79,8 +234,7 @@ function runElmApp(
|
|
|
79
234
|
mode,
|
|
80
235
|
pagePath,
|
|
81
236
|
request,
|
|
82
|
-
|
|
83
|
-
fs,
|
|
237
|
+
addBackendTaskWatcher,
|
|
84
238
|
hasFsAccess
|
|
85
239
|
) {
|
|
86
240
|
const isDevServer = mode !== "build";
|
|
@@ -94,10 +248,10 @@ function runElmApp(
|
|
|
94
248
|
.replace(/content\.dat\/?$/, "");
|
|
95
249
|
|
|
96
250
|
const modifiedRequest = { ...request, path: route };
|
|
97
|
-
// console.log("StaticHttp cache keys", Object.keys(global.staticHttpCache));
|
|
98
251
|
app = elmModule.Elm.Main.init({
|
|
99
252
|
flags: {
|
|
100
253
|
mode,
|
|
254
|
+
compatibilityKey,
|
|
101
255
|
request: {
|
|
102
256
|
payload: modifiedRequest,
|
|
103
257
|
kind: "single-page",
|
|
@@ -127,9 +281,6 @@ function runElmApp(
|
|
|
127
281
|
console.log(fromElm.value);
|
|
128
282
|
} else if (fromElm.tag === "ApiResponse") {
|
|
129
283
|
const args = fromElm.args[0];
|
|
130
|
-
if (mode === "build") {
|
|
131
|
-
global.staticHttpCache = args.staticHttpCache;
|
|
132
|
-
}
|
|
133
284
|
|
|
134
285
|
resolve({
|
|
135
286
|
kind: "api-response",
|
|
@@ -139,10 +290,6 @@ function runElmApp(
|
|
|
139
290
|
});
|
|
140
291
|
} else if (fromElm.tag === "PageProgress") {
|
|
141
292
|
const args = fromElm.args[0];
|
|
142
|
-
if (mode === "build") {
|
|
143
|
-
global.staticHttpCache = args.staticHttpCache;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
293
|
if (isBytes) {
|
|
147
294
|
resolve({
|
|
148
295
|
kind: "bytes",
|
|
@@ -161,30 +308,37 @@ function runElmApp(
|
|
|
161
308
|
);
|
|
162
309
|
}
|
|
163
310
|
} 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
|
-
|
|
311
|
+
app.ports.gotBatchSub.send(
|
|
312
|
+
Object.fromEntries(
|
|
313
|
+
await Promise.all(
|
|
314
|
+
fromElm.args[0].map(([requestHash, requestToPerform]) => {
|
|
315
|
+
if (
|
|
316
|
+
requestToPerform.url !== "elm-pages-internal://port" &&
|
|
317
|
+
requestToPerform.url.startsWith("elm-pages-internal://")
|
|
318
|
+
) {
|
|
319
|
+
return runInternalJob(
|
|
320
|
+
requestHash,
|
|
321
|
+
app,
|
|
322
|
+
mode,
|
|
323
|
+
requestToPerform,
|
|
324
|
+
hasFsAccess,
|
|
325
|
+
patternsToWatch
|
|
326
|
+
);
|
|
327
|
+
} else {
|
|
328
|
+
return runHttpJob(
|
|
329
|
+
requestHash,
|
|
330
|
+
portsFile,
|
|
331
|
+
app,
|
|
332
|
+
mode,
|
|
333
|
+
requestToPerform,
|
|
334
|
+
hasFsAccess,
|
|
335
|
+
requestToPerform
|
|
336
|
+
);
|
|
337
|
+
}
|
|
338
|
+
})
|
|
339
|
+
)
|
|
340
|
+
)
|
|
341
|
+
);
|
|
188
342
|
} else if (fromElm.tag === "Errors") {
|
|
189
343
|
foundErrors = true;
|
|
190
344
|
reject(fromElm.args[0].errorsJson);
|
|
@@ -195,7 +349,7 @@ function runElmApp(
|
|
|
195
349
|
app.ports.toJsPort.subscribe(portHandler);
|
|
196
350
|
app.ports.sendPageData.subscribe(portHandler);
|
|
197
351
|
}).finally(() => {
|
|
198
|
-
|
|
352
|
+
addBackendTaskWatcher(patternsToWatch);
|
|
199
353
|
try {
|
|
200
354
|
killApp();
|
|
201
355
|
killApp = null;
|
|
@@ -244,17 +398,16 @@ async function outputString(
|
|
|
244
398
|
/** @typedef { { head: any[]; errors: any[]; contentJson: any[]; html: string; route: string; title: string; } } Arg */
|
|
245
399
|
|
|
246
400
|
async function runHttpJob(
|
|
401
|
+
requestHash,
|
|
247
402
|
portsFile,
|
|
248
403
|
app,
|
|
249
404
|
mode,
|
|
250
405
|
requestToPerform,
|
|
251
|
-
fs,
|
|
252
406
|
hasFsAccess,
|
|
253
407
|
useCache
|
|
254
408
|
) {
|
|
255
|
-
pendingDataSourceCount += 1;
|
|
256
409
|
try {
|
|
257
|
-
const
|
|
410
|
+
const lookupResponse = await lookupOrPerform(
|
|
258
411
|
portsFile,
|
|
259
412
|
mode,
|
|
260
413
|
requestToPerform,
|
|
@@ -262,17 +415,31 @@ async function runHttpJob(
|
|
|
262
415
|
useCache
|
|
263
416
|
);
|
|
264
417
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
418
|
+
if (lookupResponse.kind === "cache-response-path") {
|
|
419
|
+
const responseFilePath = lookupResponse.value;
|
|
420
|
+
return [
|
|
421
|
+
requestHash,
|
|
422
|
+
{
|
|
423
|
+
request: requestToPerform,
|
|
424
|
+
response: JSON.parse(
|
|
425
|
+
(await fs.promises.readFile(responseFilePath, "utf8")).toString()
|
|
426
|
+
),
|
|
427
|
+
},
|
|
428
|
+
];
|
|
429
|
+
} else if (lookupResponse.kind === "response-json") {
|
|
430
|
+
return [
|
|
431
|
+
requestHash,
|
|
432
|
+
{
|
|
433
|
+
request: requestToPerform,
|
|
434
|
+
response: lookupResponse.value,
|
|
435
|
+
},
|
|
436
|
+
];
|
|
437
|
+
} else {
|
|
438
|
+
throw `Unexpected kind ${lookupResponse}`;
|
|
439
|
+
}
|
|
271
440
|
} catch (error) {
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
pendingDataSourceCount -= 1;
|
|
275
|
-
flushIfDone(app);
|
|
441
|
+
console.log("@@@ERROR", error);
|
|
442
|
+
// sendError(app, error);
|
|
276
443
|
}
|
|
277
444
|
}
|
|
278
445
|
|
|
@@ -290,46 +457,54 @@ function jsonResponse(request, json) {
|
|
|
290
457
|
}
|
|
291
458
|
|
|
292
459
|
async function runInternalJob(
|
|
460
|
+
requestHash,
|
|
293
461
|
app,
|
|
294
462
|
mode,
|
|
295
463
|
requestToPerform,
|
|
296
|
-
fs,
|
|
297
464
|
hasFsAccess,
|
|
298
465
|
patternsToWatch
|
|
299
466
|
) {
|
|
300
467
|
try {
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
if (requestToPerform.url === "elm-pages-internal://read-file") {
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
468
|
+
if (requestToPerform.url === "elm-pages-internal://log") {
|
|
469
|
+
return [requestHash, await runLogJob(requestToPerform)];
|
|
470
|
+
} else if (requestToPerform.url === "elm-pages-internal://read-file") {
|
|
471
|
+
return [
|
|
472
|
+
requestHash,
|
|
473
|
+
await readFileJobNew(requestToPerform, patternsToWatch),
|
|
474
|
+
];
|
|
307
475
|
} else if (requestToPerform.url === "elm-pages-internal://glob") {
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
476
|
+
return [requestHash, await runGlobNew(requestToPerform, patternsToWatch)];
|
|
477
|
+
} else if (requestToPerform.url === "elm-pages-internal://randomSeed") {
|
|
478
|
+
return [
|
|
479
|
+
requestHash,
|
|
480
|
+
jsonResponse(
|
|
481
|
+
requestToPerform,
|
|
482
|
+
crypto.getRandomValues(new Uint32Array(1))[0]
|
|
483
|
+
),
|
|
484
|
+
];
|
|
485
|
+
} else if (requestToPerform.url === "elm-pages-internal://now") {
|
|
486
|
+
return [requestHash, jsonResponse(requestToPerform, Date.now())];
|
|
311
487
|
} else if (requestToPerform.url === "elm-pages-internal://env") {
|
|
312
|
-
|
|
313
|
-
await runEnvJob(requestToPerform, patternsToWatch)
|
|
314
|
-
);
|
|
488
|
+
return [requestHash, await runEnvJob(requestToPerform, patternsToWatch)];
|
|
315
489
|
} else if (requestToPerform.url === "elm-pages-internal://encrypt") {
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
490
|
+
return [
|
|
491
|
+
requestHash,
|
|
492
|
+
await runEncryptJob(requestToPerform, patternsToWatch),
|
|
493
|
+
];
|
|
319
494
|
} else if (requestToPerform.url === "elm-pages-internal://decrypt") {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
495
|
+
return [
|
|
496
|
+
requestHash,
|
|
497
|
+
await runDecryptJob(requestToPerform, patternsToWatch),
|
|
498
|
+
];
|
|
499
|
+
} else if (requestToPerform.url === "elm-pages-internal://write-file") {
|
|
500
|
+
return [requestHash, await runWriteFileJob(requestToPerform)];
|
|
323
501
|
} else {
|
|
324
|
-
throw `Unexpected internal
|
|
502
|
+
throw `Unexpected internal BackendTask request format: ${kleur.yellow(
|
|
325
503
|
JSON.stringify(2, null, requestToPerform)
|
|
326
504
|
)}`;
|
|
327
505
|
}
|
|
328
506
|
} catch (error) {
|
|
329
507
|
sendError(app, error);
|
|
330
|
-
} finally {
|
|
331
|
-
pendingDataSourceCount -= 1;
|
|
332
|
-
flushIfDone(app);
|
|
333
508
|
}
|
|
334
509
|
}
|
|
335
510
|
|
|
@@ -344,6 +519,7 @@ async function readFileJobNew(req, patternsToWatch) {
|
|
|
344
519
|
path.join(process.env.LAMBDA_TASK_ROOT || process.cwd(), filePath)
|
|
345
520
|
)
|
|
346
521
|
).toString();
|
|
522
|
+
// TODO does this throw an error if there is invalid frontmatter?
|
|
347
523
|
const parsedFile = matter(fileContents);
|
|
348
524
|
|
|
349
525
|
return jsonResponse(req, {
|
|
@@ -352,10 +528,24 @@ async function readFileJobNew(req, patternsToWatch) {
|
|
|
352
528
|
rawFile: fileContents,
|
|
353
529
|
});
|
|
354
530
|
} catch (error) {
|
|
531
|
+
return jsonResponse(req, {
|
|
532
|
+
errorCode: error.code,
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
async function runWriteFileJob(req) {
|
|
537
|
+
const data = req.body.args[0];
|
|
538
|
+
try {
|
|
539
|
+
const fullPathToWrite = path.join(process.cwd(), data.path);
|
|
540
|
+
await fsPromises.mkdir(path.dirname(fullPathToWrite), { recursive: true });
|
|
541
|
+
await fsPromises.writeFile(fullPathToWrite, data.body);
|
|
542
|
+
return jsonResponse(req, null);
|
|
543
|
+
} catch (error) {
|
|
544
|
+
console.trace(error);
|
|
355
545
|
throw {
|
|
356
|
-
title: "
|
|
357
|
-
message: `
|
|
358
|
-
|
|
546
|
+
title: "BackendTask Error",
|
|
547
|
+
message: `BackendTask.Generator.writeFile failed for file path: ${kleur.yellow(
|
|
548
|
+
data.path
|
|
359
549
|
)}\n${kleur.red(error.toString())}`,
|
|
360
550
|
};
|
|
361
551
|
}
|
|
@@ -364,7 +554,7 @@ async function readFileJobNew(req, patternsToWatch) {
|
|
|
364
554
|
async function runGlobNew(req, patternsToWatch) {
|
|
365
555
|
try {
|
|
366
556
|
const { pattern, options } = req.body.args[0];
|
|
367
|
-
const matchedPaths = await globby(pattern, options);
|
|
557
|
+
const matchedPaths = await globby.globby(pattern, options);
|
|
368
558
|
patternsToWatch.add(pattern);
|
|
369
559
|
|
|
370
560
|
return jsonResponse(
|
|
@@ -382,6 +572,15 @@ async function runGlobNew(req, patternsToWatch) {
|
|
|
382
572
|
}
|
|
383
573
|
}
|
|
384
574
|
|
|
575
|
+
async function runLogJob(req) {
|
|
576
|
+
try {
|
|
577
|
+
console.log(req.body.args[0].message);
|
|
578
|
+
return jsonResponse(req, null);
|
|
579
|
+
} catch (e) {
|
|
580
|
+
console.log(`Error performing env '${JSON.stringify(req.body)}'`);
|
|
581
|
+
throw e;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
385
584
|
async function runEnvJob(req, patternsToWatch) {
|
|
386
585
|
try {
|
|
387
586
|
const expectedEnv = req.body.args[0];
|
|
@@ -402,7 +601,7 @@ async function runEncryptJob(req, patternsToWatch) {
|
|
|
402
601
|
);
|
|
403
602
|
} catch (e) {
|
|
404
603
|
throw {
|
|
405
|
-
title: "
|
|
604
|
+
title: "BackendTask Encrypt Error",
|
|
406
605
|
message:
|
|
407
606
|
e.toString() + e.stack + "\n\n" + JSON.stringify(rawRequest, null, 2),
|
|
408
607
|
};
|
|
@@ -419,32 +618,13 @@ async function runDecryptJob(req, patternsToWatch) {
|
|
|
419
618
|
return jsonResponse(req, JSON.parse(signed || "null"));
|
|
420
619
|
} catch (e) {
|
|
421
620
|
throw {
|
|
422
|
-
title: "
|
|
621
|
+
title: "BackendTask Decrypt Error",
|
|
423
622
|
message:
|
|
424
623
|
e.toString() + e.stack + "\n\n" + JSON.stringify(rawRequest, null, 2),
|
|
425
624
|
};
|
|
426
625
|
}
|
|
427
626
|
}
|
|
428
627
|
|
|
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
628
|
/**
|
|
449
629
|
* @param {{ ports: { fromJsPort: { send: (arg0: { tag: string; data: any; }) => void; }; }; }} app
|
|
450
630
|
* @param {{ message: string; title: string; }} error
|