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.
Files changed (123) hide show
  1. package/README.md +10 -1
  2. package/codegen/{elm-pages-codegen.js → elm-pages-codegen.cjs} +2864 -2589
  3. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmi +0 -0
  4. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmo +0 -0
  5. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateDataTest.elmo +0 -0
  6. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  7. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  8. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  9. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm.json +1 -1
  10. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1327 -122
  11. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Runner.elm.js +15295 -13271
  12. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  13. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_supervisor.js +4 -4
  14. package/generator/dead-code-review/elm.json +8 -6
  15. package/generator/dead-code-review/src/Pages/Review/DeadCodeEliminateData.elm +59 -10
  16. package/generator/dead-code-review/tests/Pages/Review/DeadCodeEliminateDataTest.elm +52 -36
  17. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  18. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  19. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  20. package/generator/review/elm-stuff/tests-0.19.1/elm.json +1 -1
  21. package/generator/review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1327 -122
  22. package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +14621 -12637
  23. package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  24. package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +4 -4
  25. package/generator/review/elm.json +8 -8
  26. package/generator/src/RouteBuilder.elm +113 -107
  27. package/generator/src/SharedTemplate.elm +3 -2
  28. package/generator/src/SiteConfig.elm +3 -2
  29. package/generator/src/basepath-middleware.js +3 -3
  30. package/generator/src/build.js +123 -87
  31. package/generator/src/cli.js +256 -77
  32. package/generator/src/codegen.js +29 -27
  33. package/generator/src/compatibility-key.js +3 -0
  34. package/generator/src/compile-elm.js +25 -25
  35. package/generator/src/config.js +39 -0
  36. package/generator/src/copy-dir.js +2 -2
  37. package/generator/src/dev-server.js +150 -133
  38. package/generator/src/dir-helpers.js +9 -26
  39. package/generator/src/elm-codegen.js +5 -4
  40. package/generator/src/elm-file-constants.js +2 -3
  41. package/generator/src/error-formatter.js +12 -11
  42. package/generator/src/file-helpers.js +3 -4
  43. package/generator/src/generate-template-module-connector.js +23 -22
  44. package/generator/src/init.js +9 -8
  45. package/generator/src/pre-render-html.js +39 -28
  46. package/generator/src/render-test.js +109 -0
  47. package/generator/src/render-worker.js +25 -28
  48. package/generator/src/render.js +322 -142
  49. package/generator/src/request-cache.js +252 -163
  50. package/generator/src/rewrite-client-elm-json.js +5 -5
  51. package/generator/src/rewrite-elm-json.js +7 -7
  52. package/generator/src/route-codegen-helpers.js +16 -31
  53. package/generator/src/seo-renderer.js +12 -7
  54. package/generator/src/vite-utils.js +77 -0
  55. package/generator/static-code/hmr.js +79 -13
  56. package/generator/template/app/Api.elm +6 -5
  57. package/generator/template/app/Effect.elm +123 -0
  58. package/generator/template/app/ErrorPage.elm +37 -6
  59. package/generator/template/app/Route/Index.elm +17 -10
  60. package/generator/template/app/Shared.elm +24 -47
  61. package/generator/template/app/Site.elm +19 -6
  62. package/generator/template/app/View.elm +1 -8
  63. package/generator/template/elm-tooling.json +0 -3
  64. package/generator/template/elm.json +34 -25
  65. package/generator/template/package.json +10 -4
  66. package/package.json +23 -22
  67. package/src/ApiRoute.elm +199 -61
  68. package/src/BackendTask/Custom.elm +325 -0
  69. package/src/BackendTask/Env.elm +90 -0
  70. package/src/{DataSource → BackendTask}/File.elm +128 -43
  71. package/src/{DataSource → BackendTask}/Glob.elm +136 -125
  72. package/src/BackendTask/Http.elm +673 -0
  73. package/src/{DataSource → BackendTask}/Internal/Glob.elm +1 -1
  74. package/src/BackendTask/Internal/Request.elm +28 -0
  75. package/src/BackendTask/Random.elm +79 -0
  76. package/src/BackendTask/Time.elm +47 -0
  77. package/src/BackendTask.elm +537 -0
  78. package/src/FatalError.elm +89 -0
  79. package/src/Form/Field.elm +21 -9
  80. package/src/Form/FieldView.elm +94 -14
  81. package/src/Form.elm +275 -400
  82. package/src/Head.elm +237 -7
  83. package/src/HtmlPrinter.elm +7 -3
  84. package/src/Internal/ApiRoute.elm +7 -5
  85. package/src/PageServerResponse.elm +6 -1
  86. package/src/Pages/FormState.elm +6 -5
  87. package/src/Pages/GeneratorProgramConfig.elm +15 -0
  88. package/src/Pages/Internal/FatalError.elm +5 -0
  89. package/src/Pages/Internal/Form.elm +21 -1
  90. package/src/Pages/{Msg.elm → Internal/Msg.elm} +26 -16
  91. package/src/Pages/Internal/Platform/Cli.elm +507 -763
  92. package/src/Pages/Internal/Platform/CompatibilityKey.elm +6 -0
  93. package/src/Pages/Internal/Platform/Effect.elm +1 -2
  94. package/src/Pages/Internal/Platform/GeneratorApplication.elm +373 -0
  95. package/src/Pages/Internal/Platform/StaticResponses.elm +73 -270
  96. package/src/Pages/Internal/Platform/ToJsPayload.elm +4 -7
  97. package/src/Pages/Internal/Platform.elm +215 -102
  98. package/src/Pages/Internal/Script.elm +17 -0
  99. package/src/Pages/Internal/StaticHttpBody.elm +35 -1
  100. package/src/Pages/Manifest.elm +29 -4
  101. package/src/Pages/PageUrl.elm +23 -9
  102. package/src/Pages/ProgramConfig.elm +14 -10
  103. package/src/Pages/Script.elm +109 -0
  104. package/src/Pages/SiteConfig.elm +3 -2
  105. package/src/Pages/StaticHttp/Request.elm +2 -2
  106. package/src/Pages/StaticHttpRequest.elm +23 -98
  107. package/src/PagesMsg.elm +92 -0
  108. package/src/Path.elm +16 -19
  109. package/src/QueryParams.elm +21 -172
  110. package/src/RequestsAndPending.elm +8 -19
  111. package/src/Result/Extra.elm +26 -0
  112. package/src/Scaffold/Form.elm +484 -0
  113. package/src/Scaffold/Route.elm +1376 -0
  114. package/src/Server/Request.elm +43 -37
  115. package/src/Server/Session.elm +34 -34
  116. package/src/Server/SetCookie.elm +1 -1
  117. package/src/Test/Html/Internal/ElmHtml/ToString.elm +8 -9
  118. package/src/DataSource/Env.elm +0 -38
  119. package/src/DataSource/Http.elm +0 -446
  120. package/src/DataSource/Internal/Request.elm +0 -20
  121. package/src/DataSource/Port.elm +0 -90
  122. package/src/DataSource.elm +0 -538
  123. package/src/Pages/Generate.elm +0 -800
@@ -1,67 +1,222 @@
1
1
  // @ts-check
2
2
 
3
- const path = require("path");
4
- const mm = require("micromatch");
5
- const matter = require("gray-matter");
6
- const globby = require("globby");
7
- const fsPromises = require("fs").promises;
8
- const preRenderHtml = require("./pre-render-html.js");
9
- const { lookupOrPerform } = require("./request-cache.js");
10
- const kleur = require("kleur");
11
- const cookie = require("cookie-signature");
12
- kleur.enabled = true;
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
- module.exports =
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} addDataSourceWatcher
29
- * @param {boolean} hasFsAccess
30
- * @returns
31
- */
32
- async function run(
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
- addDataSourceWatcher,
55
+ addBackendTaskWatcher,
40
56
  hasFsAccess
41
- ) {
42
- const { fs, resetInMemoryFs } = require("./request-cache-fs.js")(
43
- hasFsAccess
44
- );
45
- resetInMemoryFs();
46
- foundErrors = false;
47
- pendingDataSourceResponses = [];
48
- pendingDataSourceCount = 0;
49
- // since init/update are never called in pre-renders, and DataSource.Http is called using pure NodeJS HTTP fetching
50
- // we can provide a fake HTTP instead of xhr2 (which is otherwise needed for Elm HTTP requests from Node)
51
- XMLHttpRequest = {};
52
- const result = await runElmApp(
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
- basePath,
85
+ "",
55
86
  elmModule,
56
- mode,
57
- path,
58
- request,
59
- addDataSourceWatcher,
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} addDataSourceWatcher
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
- addDataSourceWatcher,
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
- const requestToPerform = fromElm.args[0];
165
- if (
166
- requestToPerform.url !== "elm-pages-internal://port" &&
167
- requestToPerform.url.startsWith("elm-pages-internal://")
168
- ) {
169
- runInternalJob(
170
- app,
171
- mode,
172
- requestToPerform,
173
- fs,
174
- hasFsAccess,
175
- patternsToWatch
176
- );
177
- } else {
178
- runHttpJob(
179
- portsFile,
180
- app,
181
- mode,
182
- requestToPerform,
183
- fs,
184
- hasFsAccess,
185
- fromElm.args[1]
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
- addDataSourceWatcher(patternsToWatch);
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 responseFilePath = await lookupOrPerform(
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
- pendingDataSourceResponses.push({
266
- request: requestToPerform,
267
- response: JSON.parse(
268
- (await fs.promises.readFile(responseFilePath, "utf8")).toString()
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
- sendError(app, error);
273
- } finally {
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
- pendingDataSourceCount += 1;
302
-
303
- if (requestToPerform.url === "elm-pages-internal://read-file") {
304
- pendingDataSourceResponses.push(
305
- await readFileJobNew(requestToPerform, patternsToWatch)
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
- pendingDataSourceResponses.push(
309
- await runGlobNew(requestToPerform, patternsToWatch)
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
- pendingDataSourceResponses.push(
313
- await runEnvJob(requestToPerform, patternsToWatch)
314
- );
488
+ return [requestHash, await runEnvJob(requestToPerform, patternsToWatch)];
315
489
  } else if (requestToPerform.url === "elm-pages-internal://encrypt") {
316
- pendingDataSourceResponses.push(
317
- await runEncryptJob(requestToPerform, patternsToWatch)
318
- );
490
+ return [
491
+ requestHash,
492
+ await runEncryptJob(requestToPerform, patternsToWatch),
493
+ ];
319
494
  } else if (requestToPerform.url === "elm-pages-internal://decrypt") {
320
- pendingDataSourceResponses.push(
321
- await runDecryptJob(requestToPerform, patternsToWatch)
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 DataSource request format: ${kleur.yellow(
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: "DataSource.File Error",
357
- message: `A DataSource.File read failed because I couldn't find this file: ${kleur.yellow(
358
- filePath
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: "DataSource Encrypt Error",
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: "DataSource Decrypt Error",
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