testeranto 0.110.0 → 0.112.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.
@@ -2,20 +2,17 @@ import { createRequire } from 'module';const require = createRequire(import.meta
2
2
 
3
3
  // src/run.ts
4
4
  import ansiC2 from "ansi-colors";
5
- import { watch } from "fs";
6
- import path3 from "path";
7
- import crypto from "node:crypto";
8
- import fs2 from "fs";
9
- import tsc from "tsc-prog";
10
- import { ESLint } from "eslint";
11
- import ts from "typescript";
12
5
  import readline from "readline";
13
6
 
14
7
  // src/PM/main.ts
15
- import fs from "fs";
8
+ import ts from "typescript";
9
+ import fs, { watch } from "fs";
16
10
  import path2 from "path";
17
11
  import puppeteer from "puppeteer-core";
18
12
  import ansiC from "ansi-colors";
13
+ import crypto from "node:crypto";
14
+ import { ESLint } from "eslint";
15
+ import tsc from "tsc-prog";
19
16
 
20
17
  // src/utils.ts
21
18
  import path from "path";
@@ -27,14 +24,6 @@ var tscPather = (entryPoint, platform) => {
27
24
  `type_errors.txt`
28
25
  );
29
26
  };
30
- var tscExitCodePather = (entryPoint, platform) => {
31
- return path.join(
32
- "./docs/",
33
- platform,
34
- entryPoint.split(".").slice(0, -1).join("."),
35
- `type_errors.txt`
36
- );
37
- };
38
27
  var lintPather = (entryPoint, platform) => {
39
28
  return path.join(
40
29
  "./docs/",
@@ -43,33 +32,59 @@ var lintPather = (entryPoint, platform) => {
43
32
  `lint_errors.json`
44
33
  );
45
34
  };
46
- var lintExitCodePather = (entryPoint, platform) => {
47
- return path.join(
48
- "./docs/",
49
- platform,
50
- entryPoint.split(".").slice(0, -1).join("."),
51
- `lint_errors.txt`
52
- );
53
- };
54
- var bddExitCodePather = (entryPoint, platform) => {
55
- return path.join(
56
- "./docs/",
57
- platform,
58
- entryPoint.split(".").slice(0, -1).join("."),
59
- `bdd_errors.txt`
60
- );
61
- };
62
35
 
63
36
  // src/PM/index.ts
64
37
  var PM = class {
65
38
  };
66
39
 
67
40
  // src/PM/main.ts
41
+ var eslint = new ESLint();
42
+ var formatter = await eslint.loadFormatter(
43
+ "./node_modules/testeranto/dist/prebuild/esbuildConfigs/eslint-formatter-testeranto.mjs"
44
+ );
45
+ var changes = {};
46
+ var fileHashes = {};
68
47
  var fileStreams3 = [];
69
48
  var fPaths = [];
70
49
  var files = {};
71
50
  var recorders = {};
72
51
  var screenshots = {};
52
+ async function fileHash(filePath, algorithm = "md5") {
53
+ return new Promise((resolve, reject) => {
54
+ const hash = crypto.createHash(algorithm);
55
+ const fileStream = fs.createReadStream(filePath);
56
+ fileStream.on("data", (data) => {
57
+ hash.update(data);
58
+ });
59
+ fileStream.on("end", () => {
60
+ const fileHash2 = hash.digest("hex");
61
+ resolve(fileHash2);
62
+ });
63
+ fileStream.on("error", (error) => {
64
+ reject(`Error reading file: ${error.message}`);
65
+ });
66
+ });
67
+ }
68
+ var getRunnables = (tests, payload = {
69
+ nodeEntryPoints: {},
70
+ webEntryPoints: {}
71
+ }) => {
72
+ return tests.reduce((pt, cv, cndx, cry) => {
73
+ if (cv[1] === "node") {
74
+ pt.nodeEntryPoints[cv[0]] = path2.resolve(
75
+ `./docs/node/${cv[0].split(".").slice(0, -1).concat("mjs").join(".")}`
76
+ );
77
+ } else if (cv[1] === "web") {
78
+ pt.webEntryPoints[cv[0]] = path2.resolve(
79
+ `./docs/web/${cv[0].split(".").slice(0, -1).concat("mjs").join(".")}`
80
+ );
81
+ }
82
+ if (cv[3].length) {
83
+ getRunnables(cv[3], payload);
84
+ }
85
+ return pt;
86
+ }, payload);
87
+ };
73
88
  var statusMessagePretty = (failures, test) => {
74
89
  if (failures === 0) {
75
90
  console.log(ansiC.green(ansiC.inverse(`> ${test} completed successfully`)));
@@ -86,6 +101,15 @@ async function writeFileAndCreateDir(filePath, data) {
86
101
  console.error(`Error writing file: ${error}`);
87
102
  }
88
103
  }
104
+ var filesHash = async (files2, algorithm = "md5") => {
105
+ return new Promise((resolve, reject) => {
106
+ resolve(
107
+ files2.reduce(async (mm, f) => {
108
+ return await mm + await fileHash(f);
109
+ }, Promise.resolve(""))
110
+ );
111
+ });
112
+ };
89
113
  function isValidUrl(string) {
90
114
  try {
91
115
  new URL(string);
@@ -99,27 +123,137 @@ var PM_Main = class extends PM {
99
123
  super();
100
124
  this.shutdownMode = false;
101
125
  this.bigBoard = {};
126
+ this.stop = () => {
127
+ console.log(ansiC.inverse("Testeranto-Run is shutting down gracefully..."));
128
+ this.mode = "PROD";
129
+ this.nodeMetafileWatcher.close();
130
+ this.webMetafileWatcher.close();
131
+ this.checkForShutdown();
132
+ };
133
+ this.tscCheck = async ({
134
+ entrypoint,
135
+ addableFiles,
136
+ platform
137
+ }) => {
138
+ console.log(ansiC.green(ansiC.inverse(`tsc < ${entrypoint}`)));
139
+ this.bigBoard[entrypoint].typeErrors = "?";
140
+ const program = tsc.createProgramFromConfig({
141
+ basePath: process.cwd(),
142
+ // always required, used for relative paths
143
+ configFilePath: "tsconfig.json",
144
+ // config to inherit from (optional)
145
+ compilerOptions: {
146
+ rootDir: "src",
147
+ outDir: tscPather(entrypoint, platform),
148
+ // declaration: true,
149
+ // skipLibCheck: true,
150
+ noEmit: true
151
+ },
152
+ include: addableFiles
153
+ //["src/**/*"],
154
+ // exclude: ["**/*.test.ts", "**/*.spec.ts"],
155
+ });
156
+ const tscPath = tscPather(entrypoint, platform);
157
+ let allDiagnostics = program.getSemanticDiagnostics();
158
+ const d = [];
159
+ allDiagnostics.forEach((diagnostic) => {
160
+ if (diagnostic.file) {
161
+ let { line, character } = ts.getLineAndCharacterOfPosition(
162
+ diagnostic.file,
163
+ diagnostic.start
164
+ );
165
+ let message = ts.flattenDiagnosticMessageText(
166
+ diagnostic.messageText,
167
+ "\n"
168
+ );
169
+ d.push(
170
+ `${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`
171
+ );
172
+ } else {
173
+ d.push(ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"));
174
+ }
175
+ });
176
+ fs.writeFileSync(tscPath, d.join("\n"));
177
+ this.bigBoard[entrypoint].typeErrors = d.length;
178
+ if (this.shutdownMode) {
179
+ this.checkForShutdown();
180
+ }
181
+ };
182
+ this.eslintCheck = async (entrypoint, platform, addableFiles) => {
183
+ this.bigBoard[entrypoint].staticErrors = "?";
184
+ console.log(ansiC.green(ansiC.inverse(`eslint < ${entrypoint}`)));
185
+ const results = (await eslint.lintFiles(addableFiles)).filter((r) => r.messages.length).filter((r) => {
186
+ return r.messages[0].ruleId !== null;
187
+ }).map((r) => {
188
+ delete r.source;
189
+ return r;
190
+ });
191
+ fs.writeFileSync(
192
+ lintPather(entrypoint, platform),
193
+ await formatter.format(results)
194
+ );
195
+ this.bigBoard[entrypoint].staticErrors = results.length;
196
+ if (this.shutdownMode) {
197
+ this.checkForShutdown();
198
+ }
199
+ };
200
+ this.makePrompt = async (entryPoint, addableFiles, platform) => {
201
+ this.bigBoard[entryPoint].prompt = "?";
202
+ const promptPath = path2.join(
203
+ "./docs/",
204
+ platform,
205
+ entryPoint.split(".").slice(0, -1).join("."),
206
+ `prompt.txt`
207
+ );
208
+ const testPaths = path2.join(
209
+ "./docs/",
210
+ platform,
211
+ entryPoint.split(".").slice(0, -1).join("."),
212
+ `tests.json`
213
+ );
214
+ const featuresPath = path2.join(
215
+ "./docs/",
216
+ platform,
217
+ entryPoint.split(".").slice(0, -1).join("."),
218
+ `featurePrompt.txt`
219
+ );
220
+ fs.writeFileSync(
221
+ promptPath,
222
+ `
223
+ ${addableFiles.map((x) => {
224
+ return `/add ${x}`;
225
+ }).join("\n")}
226
+
227
+ /read ${lintPather(entryPoint, platform)}
228
+ /read ${tscPather(entryPoint, platform)}
229
+ /read ${testPaths}
230
+
231
+ /load ${featuresPath}
232
+
233
+ /code Fix the failing tests described in ${testPaths}. Correct any type signature errors described in the files ${tscPather(
234
+ entryPoint,
235
+ platform
236
+ )}. Implement any method which throws "Function not implemented. Resolve the lint errors described in ${lintPather(
237
+ entryPoint,
238
+ platform
239
+ )}"
240
+ `
241
+ );
242
+ this.bigBoard[entryPoint].prompt = `aider --model deepseek/deepseek-chat --load docs/${platform}/${entryPoint.split(".").slice(0, -1).join(".")}/prompt.txt`;
243
+ if (this.shutdownMode) {
244
+ this.checkForShutdown();
245
+ }
246
+ };
102
247
  this.checkForShutdown = () => {
103
- const anyRunning = Object.values(this.bigBoard).filter((x) => x.status === "running").length > 0;
248
+ const anyRunning = Object.values(this.bigBoard).filter((x) => x.prompt === "?").length + Object.values(this.bigBoard).filter((x) => x.runTimeError === "?").length + Object.values(this.bigBoard).filter((x) => x.staticErrors === "?").length + Object.values(this.bigBoard).filter((x) => x.typeErrors === "?").length > 0;
104
249
  if (anyRunning) {
250
+ console.log(ansiC.inverse("Shutting down. Please wait"));
105
251
  } else {
106
252
  this.browser.disconnect().then(() => {
107
- const final = {
108
- timestamp: Date.now(),
109
- tests: this.configs.tests.reduce((mm, t) => {
110
- const bddErrors = fs.readFileSync(bddExitCodePather(t[0], t[1])).toString();
111
- const lintErrors = fs.readFileSync(lintExitCodePather(t[0], t[1])).toString();
112
- const typeErrors = fs.readFileSync(tscExitCodePather(t[0], t[1])).toString();
113
- mm[t[0]] = {
114
- bddErrors,
115
- lintErrors,
116
- typeErrors
117
- };
118
- return mm;
119
- }, {})
120
- };
121
- const s = JSON.stringify(final, null, 2);
122
- fs.writeFileSync("docs/summary.json", s);
253
+ fs.writeFileSync(
254
+ "docs/summary.json",
255
+ JSON.stringify(this.bigBoard, null, 2)
256
+ );
123
257
  console.log(ansiC.inverse("Goodbye"));
124
258
  process.exit();
125
259
  });
@@ -206,7 +340,6 @@ var PM_Main = class extends PM {
206
340
  this.launchWebSideCar = async (src, dest, testConfig) => {
207
341
  const d = dest + ".mjs";
208
342
  console.log(ansiC.green(ansiC.inverse(`launchWebSideCar ${src}`)));
209
- const destFolder = dest.replace(".mjs", "");
210
343
  const fileStreams2 = [];
211
344
  const doneFileStream2 = [];
212
345
  return new Promise((res, rej) => {
@@ -608,7 +741,6 @@ var PM_Main = class extends PM {
608
741
  }).join("\n")
609
742
  );
610
743
  });
611
- this.writeBigBoard();
612
744
  };
613
745
  this.receiveExitCode = (srcTest, failures) => {
614
746
  this.bigBoard[srcTest].runTimeError = failures;
@@ -616,16 +748,20 @@ var PM_Main = class extends PM {
616
748
  };
617
749
  this.writeBigBoard = () => {
618
750
  fs.writeFileSync(
619
- "./docs/bigBoard.json",
751
+ "./docs/summary.json",
620
752
  JSON.stringify(this.bigBoard, null, 2)
621
753
  );
622
754
  };
755
+ this.mode = configs.devMode ? "DEV" : "PROD";
623
756
  this.server = {};
624
757
  this.configs = configs;
625
758
  this.ports = {};
626
759
  this.configs.tests.forEach(([t]) => {
627
760
  this.bigBoard[t] = {
628
- status: "?"
761
+ runTimeError: "?",
762
+ typeErrors: "?",
763
+ staticErrors: "?",
764
+ prompt: "?"
629
765
  };
630
766
  });
631
767
  this.configs.ports.forEach((element) => {
@@ -638,8 +774,8 @@ var PM_Main = class extends PM {
638
774
  );
639
775
  await page?.waitForSelector(sel);
640
776
  };
641
- globalThis["screencastStop"] = async (path4) => {
642
- return recorders[path4].stop();
777
+ globalThis["screencastStop"] = async (path3) => {
778
+ return recorders[path3].stop();
643
779
  };
644
780
  globalThis["closePage"] = async (pageKey) => {
645
781
  const page = (await this.browser.pages()).find(
@@ -858,260 +994,44 @@ var PM_Main = class extends PM {
858
994
  throw new Error("Method not implemented.");
859
995
  }
860
996
  ////////////////////////////////////////////////////////////////////////////////
861
- async startPuppeteer(options, destfolder) {
862
- this.browser = await puppeteer.launch(options);
863
- }
864
- // goodbye = () => {
865
- // this.browser.disconnect().then(() => {
866
- // console.log("Goodbye");
867
- // process.exit();
868
- // });
869
- // };
870
- shutDown() {
871
- this.shutdownMode = true;
872
- this.checkForShutdown();
873
- }
874
- };
875
-
876
- // src/run.ts
877
- console.log(ansiC2.inverse("Press 'x' to shutdown forcefully."));
878
- readline.emitKeypressEvents(process.stdin);
879
- if (process.stdin.isTTY)
880
- process.stdin.setRawMode(true);
881
- process.stdin.on("keypress", (str, key) => {
882
- if (key.name === "x") {
883
- console.log(ansiC2.inverse("Shutting down forcefully..."));
884
- process.exit(-1);
885
- }
886
- });
887
- async function fileHash(filePath, algorithm = "md5") {
888
- return new Promise((resolve, reject) => {
889
- const hash = crypto.createHash(algorithm);
890
- const fileStream = fs2.createReadStream(filePath);
891
- fileStream.on("data", (data) => {
892
- hash.update(data);
893
- });
894
- fileStream.on("end", () => {
895
- const fileHash2 = hash.digest("hex");
896
- resolve(fileHash2);
897
- });
898
- fileStream.on("error", (error) => {
899
- reject(`Error reading file: ${error.message}`);
900
- });
901
- });
902
- }
903
- async function filesHash(files2, algorithm = "md5") {
904
- return new Promise((resolve, reject) => {
905
- resolve(
906
- files2.reduce(async (mm, f) => {
907
- return await mm + await fileHash(f);
908
- }, Promise.resolve(""))
909
- );
910
- });
911
- }
912
- var getRunnables = (tests, payload = {
913
- nodeEntryPoints: {},
914
- webEntryPoints: {}
915
- }) => {
916
- return tests.reduce((pt, cv, cndx, cry) => {
917
- if (cv[1] === "node") {
918
- pt.nodeEntryPoints[cv[0]] = path3.resolve(
919
- `./docs/node/${cv[0].split(".").slice(0, -1).concat("mjs").join(".")}`
920
- );
921
- } else if (cv[1] === "web") {
922
- pt.webEntryPoints[cv[0]] = path3.resolve(
923
- `./docs/web/${cv[0].split(".").slice(0, -1).concat("mjs").join(".")}`
924
- );
925
- }
926
- if (cv[3].length) {
927
- getRunnables(cv[3], payload);
928
- }
929
- return pt;
930
- }, payload);
931
- };
932
- var changes = {};
933
- var tscCheck = async ({
934
- entrypoint,
935
- addableFiles,
936
- platform
937
- }) => {
938
- console.log(ansiC2.green(ansiC2.inverse(`tsc < ${entrypoint}`)));
939
- const program = tsc.createProgramFromConfig({
940
- basePath: process.cwd(),
941
- // always required, used for relative paths
942
- configFilePath: "tsconfig.json",
943
- // config to inherit from (optional)
944
- compilerOptions: {
945
- rootDir: "src",
946
- outDir: tscPather(entrypoint, platform),
947
- // declaration: true,
948
- // skipLibCheck: true,
949
- noEmit: true
950
- },
951
- include: addableFiles
952
- //["src/**/*"],
953
- // exclude: ["**/*.test.ts", "**/*.spec.ts"],
954
- });
955
- const tscPath = tscPather(entrypoint, platform);
956
- let allDiagnostics = program.getSemanticDiagnostics();
957
- const d = [];
958
- allDiagnostics.forEach((diagnostic) => {
959
- if (diagnostic.file) {
960
- let { line, character } = ts.getLineAndCharacterOfPosition(
961
- diagnostic.file,
962
- diagnostic.start
963
- );
964
- let message = ts.flattenDiagnosticMessageText(
965
- diagnostic.messageText,
966
- "\n"
967
- );
968
- d.push(
969
- `${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`
970
- );
971
- } else {
972
- d.push(ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"));
973
- }
974
- });
975
- fs2.writeFileSync(tscPath, d.join("\n"));
976
- fs2.writeFileSync(
977
- tscExitCodePather(entrypoint, platform),
978
- d.length.toString()
979
- );
980
- };
981
- var eslint = new ESLint();
982
- var formatter = await eslint.loadFormatter(
983
- "./node_modules/testeranto/dist/prebuild/esbuildConfigs/eslint-formatter-testeranto.mjs"
984
- );
985
- var eslintCheck = async (entrypoint, platform, addableFiles) => {
986
- console.log(ansiC2.green(ansiC2.inverse(`eslint < ${entrypoint}`)));
987
- const results = (await eslint.lintFiles(addableFiles)).filter((r) => r.messages.length).filter((r) => {
988
- return r.messages[0].ruleId !== null;
989
- }).map((r) => {
990
- delete r.source;
991
- return r;
992
- });
993
- fs2.writeFileSync(
994
- lintPather(entrypoint, platform),
995
- await formatter.format(results)
996
- );
997
- fs2.writeFileSync(
998
- lintExitCodePather(entrypoint, platform),
999
- results.length.toString()
1000
- );
1001
- };
1002
- var makePrompt = async (entryPoint, addableFiles, platform) => {
1003
- const promptPath = path3.join(
1004
- "./docs/",
1005
- platform,
1006
- entryPoint.split(".").slice(0, -1).join("."),
1007
- `prompt.txt`
1008
- );
1009
- const testPaths = path3.join(
1010
- "./docs/",
1011
- platform,
1012
- entryPoint.split(".").slice(0, -1).join("."),
1013
- `tests.json`
1014
- );
1015
- const featuresPath = path3.join(
1016
- "./docs/",
1017
- platform,
1018
- entryPoint.split(".").slice(0, -1).join("."),
1019
- `featurePrompt.txt`
1020
- );
1021
- fs2.writeFileSync(
1022
- promptPath,
1023
- `
1024
- ${addableFiles.map((x) => {
1025
- return `/add ${x}`;
1026
- }).join("\n")}
1027
-
1028
- /read ${lintPather(entryPoint, platform)}
1029
- /read ${tscPather(entryPoint, platform)}
1030
- /read ${testPaths}
1031
-
1032
- /load ${featuresPath}
1033
-
1034
- /code Fix the failing tests described in ${testPaths}. Correct any type signature errors described in the files ${tscPather(
1035
- entryPoint,
1036
- platform
1037
- )}. Implement any method which throws "Function not implemented. Resolve the lint errors described in ${lintPather(
1038
- entryPoint,
1039
- platform
1040
- )}"
1041
- `
1042
- );
1043
- };
1044
- var metafileOutputs = async (platform) => {
1045
- const metafile = JSON.parse(
1046
- fs2.readFileSync(`docs/${platform}/metafile.json`).toString()
1047
- ).metafile;
1048
- if (!metafile)
1049
- return;
1050
- const outputs = metafile.outputs;
1051
- Object.keys(outputs).forEach(async (k) => {
1052
- const addableFiles = Object.keys(outputs[k].inputs).filter((i) => {
1053
- if (!fs2.existsSync(i))
1054
- return false;
1055
- if (i.startsWith("node_modules"))
1056
- return false;
1057
- return true;
1058
- });
1059
- const f = `${k.split(".").slice(0, -1).join(".")}/`;
1060
- if (!fs2.existsSync(f)) {
1061
- fs2.mkdirSync(f);
1062
- }
1063
- const entrypoint = outputs[k].entryPoint;
1064
- if (entrypoint) {
1065
- const changeDigest = await filesHash(addableFiles);
1066
- if (changeDigest === changes[entrypoint]) {
1067
- } else {
1068
- changes[entrypoint] = changeDigest;
1069
- tscCheck({ platform, addableFiles, entrypoint });
1070
- eslintCheck(entrypoint, platform, addableFiles);
1071
- makePrompt(entrypoint, addableFiles, platform);
997
+ async metafileOutputs(platform) {
998
+ const metafile = JSON.parse(
999
+ fs.readFileSync(`docs/${platform}/metafile.json`).toString()
1000
+ ).metafile;
1001
+ if (!metafile)
1002
+ return;
1003
+ const outputs = metafile.outputs;
1004
+ Object.keys(outputs).forEach(async (k) => {
1005
+ const addableFiles = Object.keys(outputs[k].inputs).filter((i) => {
1006
+ if (!fs.existsSync(i))
1007
+ return false;
1008
+ if (i.startsWith("node_modules"))
1009
+ return false;
1010
+ return true;
1011
+ });
1012
+ const f = `${k.split(".").slice(0, -1).join(".")}/`;
1013
+ if (!fs.existsSync(f)) {
1014
+ fs.mkdirSync(f);
1072
1015
  }
1073
- }
1074
- });
1075
- };
1076
- import(process.cwd() + "/" + process.argv[2]).then(async (module) => {
1077
- const rawConfig = module.default;
1078
- const config = {
1079
- ...rawConfig,
1080
- buildDir: process.cwd() + "/" + rawConfig.outdir
1081
- };
1082
- let mode = config.devMode ? "DEV" : "PROD";
1083
- const fileHashes = {};
1084
- let pm = new PM_Main(config);
1085
- console.log(ansiC2.inverse(`Press 'q' to shutdown gracefully`));
1086
- process.stdin.on("keypress", (str, key) => {
1087
- if (key.name === "q") {
1088
- console.log(
1089
- ansiC2.inverse("Testeranto-Run is shutting down gracefully...")
1090
- );
1091
- mode = "PROD";
1092
- nodeMetafileWatcher.close();
1093
- webMetafileWatcher.close();
1094
- pm.shutDown();
1095
- }
1096
- });
1097
- metafileOutputs("node");
1098
- const nodeMetafileWatcher = watch(
1099
- "docs/node/metafile.json",
1100
- async (e, filename) => {
1101
- console.log(ansiC2.green(ansiC2.inverse(`< ${e} ${filename} (node)`)));
1102
- metafileOutputs("node");
1103
- }
1104
- );
1105
- metafileOutputs("web");
1106
- const webMetafileWatcher = watch(
1107
- "docs/web/metafile.json",
1108
- async (e, filename) => {
1109
- console.log(ansiC2.green(ansiC2.inverse(`< ${e} ${filename} (web)`)));
1110
- metafileOutputs("web");
1111
- }
1112
- );
1113
- await pm.startPuppeteer(
1114
- {
1016
+ const entrypoint = outputs[k].entryPoint;
1017
+ if (entrypoint) {
1018
+ const changeDigest = await filesHash(addableFiles);
1019
+ if (changeDigest === changes[entrypoint]) {
1020
+ } else {
1021
+ changes[entrypoint] = changeDigest;
1022
+ this.tscCheck({
1023
+ platform,
1024
+ addableFiles,
1025
+ entrypoint: "./" + entrypoint
1026
+ });
1027
+ this.eslintCheck("./" + entrypoint, platform, addableFiles);
1028
+ this.makePrompt("./" + entrypoint, addableFiles, platform);
1029
+ }
1030
+ }
1031
+ });
1032
+ }
1033
+ async start() {
1034
+ this.browser = await puppeteer.launch({
1115
1035
  slowMo: 1,
1116
1036
  // timeout: 1,
1117
1037
  waitForInitialPage: false,
@@ -1153,38 +1073,81 @@ import(process.cwd() + "/" + process.argv[2]).then(async (module) => {
1153
1073
  // "--disk-cache-size=1",
1154
1074
  // "--start-maximized",
1155
1075
  ]
1156
- },
1157
- "."
1158
- );
1159
- const { nodeEntryPoints, webEntryPoints } = getRunnables(config.tests);
1160
- Object.entries(nodeEntryPoints).forEach(
1161
- ([k, outputFile]) => {
1162
- pm.launchNode(k, outputFile);
1163
- try {
1076
+ });
1077
+ const { nodeEntryPoints, webEntryPoints } = getRunnables(
1078
+ this.configs.tests
1079
+ );
1080
+ Object.entries(nodeEntryPoints).forEach(
1081
+ ([k, outputFile]) => {
1082
+ this.launchNode(k, outputFile);
1083
+ try {
1084
+ watch(outputFile, async (e, filename) => {
1085
+ const hash = await fileHash(outputFile);
1086
+ if (fileHashes[k] !== hash) {
1087
+ fileHashes[k] = hash;
1088
+ console.log(ansiC.green(ansiC.inverse(`< ${e} ${filename}`)));
1089
+ this.launchNode(k, outputFile);
1090
+ }
1091
+ });
1092
+ } catch (e) {
1093
+ console.error(e);
1094
+ }
1095
+ }
1096
+ );
1097
+ Object.entries(webEntryPoints).forEach(
1098
+ ([k, outputFile]) => {
1099
+ this.launchWeb(k, outputFile);
1164
1100
  watch(outputFile, async (e, filename) => {
1165
1101
  const hash = await fileHash(outputFile);
1166
1102
  if (fileHashes[k] !== hash) {
1167
1103
  fileHashes[k] = hash;
1168
- console.log(ansiC2.green(ansiC2.inverse(`< ${e} ${filename}`)));
1169
- pm.launchNode(k, outputFile);
1104
+ console.log(ansiC.green(ansiC.inverse(`< ${e} ${filename}`)));
1105
+ this.launchWeb(k, outputFile);
1170
1106
  }
1171
1107
  });
1172
- } catch (e) {
1173
- console.error(e);
1174
1108
  }
1109
+ );
1110
+ this.metafileOutputs("node");
1111
+ this.nodeMetafileWatcher = watch(
1112
+ "docs/node/metafile.json",
1113
+ async (e, filename) => {
1114
+ console.log(ansiC.green(ansiC.inverse(`< ${e} ${filename} (node)`)));
1115
+ this.metafileOutputs("node");
1116
+ }
1117
+ );
1118
+ this.metafileOutputs("web");
1119
+ this.webMetafileWatcher = watch(
1120
+ "docs/web/metafile.json",
1121
+ async (e, filename) => {
1122
+ console.log(ansiC.green(ansiC.inverse(`< ${e} ${filename} (web)`)));
1123
+ this.metafileOutputs("web");
1124
+ }
1125
+ );
1126
+ }
1127
+ };
1128
+
1129
+ // src/run.ts
1130
+ readline.emitKeypressEvents(process.stdin);
1131
+ if (process.stdin.isTTY)
1132
+ process.stdin.setRawMode(true);
1133
+ console.log(ansiC2.inverse("Press 'x' to shutdown forcefully."));
1134
+ process.stdin.on("keypress", (str, key) => {
1135
+ if (key.name === "x") {
1136
+ console.log(ansiC2.inverse("Shutting down forcefully..."));
1137
+ process.exit(-1);
1138
+ }
1139
+ });
1140
+ import(process.cwd() + "/" + process.argv[2]).then(async (module) => {
1141
+ const rawConfig = module.default;
1142
+ const config = {
1143
+ ...rawConfig,
1144
+ buildDir: process.cwd() + "/" + rawConfig.outdir
1145
+ };
1146
+ const pm = new PM_Main(config);
1147
+ pm.start();
1148
+ process.stdin.on("keypress", (str, key) => {
1149
+ if (key.name === "q") {
1150
+ pm.stop();
1175
1151
  }
1176
- );
1177
- Object.entries(webEntryPoints).forEach(
1178
- ([k, outputFile]) => {
1179
- pm.launchWeb(k, outputFile);
1180
- watch(outputFile, async (e, filename) => {
1181
- const hash = await fileHash(outputFile);
1182
- if (fileHashes[k] !== hash) {
1183
- fileHashes[k] = hash;
1184
- console.log(ansiC2.green(ansiC2.inverse(`< ${e} ${filename}`)));
1185
- pm.launchWeb(k, outputFile);
1186
- }
1187
- });
1188
- }
1189
- );
1152
+ });
1190
1153
  });