@reventlessdev/reventless-gwt 1.0.0-alpha.115 → 1.0.0-alpha.116

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 (91) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/package.json +5 -12
  3. package/rescript.json +0 -1
  4. package/bin/reventless-dev.mjs +0 -21
  5. package/src/Bind.res +0 -29
  6. package/src/Bind.res.mjs +0 -22
  7. package/src/BuildClassifier.res +0 -147
  8. package/src/BuildClassifier.res.mjs +0 -136
  9. package/src/Cancellation.res +0 -37
  10. package/src/Cancellation.res.mjs +0 -46
  11. package/src/ChildProcess.res +0 -102
  12. package/src/ChildProcess.res.mjs +0 -107
  13. package/src/Cli.res +0 -889
  14. package/src/Cli.res.mjs +0 -944
  15. package/src/Collector.res +0 -222
  16. package/src/Collector.res.mjs +0 -228
  17. package/src/ComponentMeta.res +0 -77
  18. package/src/ComponentMeta.res.mjs +0 -91
  19. package/src/ComponentScan.res +0 -101
  20. package/src/ComponentScan.res.mjs +0 -92
  21. package/src/Discovery.res +0 -102
  22. package/src/Discovery.res.mjs +0 -86
  23. package/src/DomainDeadCode.res +0 -98
  24. package/src/DomainDeadCode.res.mjs +0 -72
  25. package/src/DomainGraph.res +0 -0
  26. package/src/DomainGraph.res.mjs +0 -0
  27. package/src/ExnMessage.res +0 -14
  28. package/src/ExnMessage.res.mjs +0 -17
  29. package/src/ExnReflect.mjs +0 -24
  30. package/src/Filter.res +0 -45
  31. package/src/Filter.res.mjs +0 -47
  32. package/src/FormatterHuman.res +0 -109
  33. package/src/FormatterHuman.res.mjs +0 -115
  34. package/src/FormatterJson.res +0 -264
  35. package/src/FormatterJson.res.mjs +0 -322
  36. package/src/FormatterJunit.res +0 -93
  37. package/src/FormatterJunit.res.mjs +0 -90
  38. package/src/FormatterTap.res +0 -100
  39. package/src/FormatterTap.res.mjs +0 -131
  40. package/src/FormatterVsCode.res +0 -352
  41. package/src/FormatterVsCode.res.mjs +0 -546
  42. package/src/Loader.res +0 -24
  43. package/src/Loader.res.mjs +0 -23
  44. package/src/PackageScan.res +0 -80
  45. package/src/PackageScan.res.mjs +0 -81
  46. package/src/PlatformRunner.res +0 -191
  47. package/src/PlatformRunner.res.mjs +0 -178
  48. package/src/PlatformScan.res +0 -141
  49. package/src/PlatformScan.res.mjs +0 -124
  50. package/src/ProcessManager.res +0 -135
  51. package/src/ProcessManager.res.mjs +0 -119
  52. package/src/RunWorker.res +0 -24
  53. package/src/RunWorker.res.mjs +0 -16
  54. package/src/RunnerTypes.res +0 -68
  55. package/src/RunnerTypes.res.mjs +0 -60
  56. package/src/ScanIgnore.res +0 -11
  57. package/src/ScanIgnore.res.mjs +0 -23
  58. package/src/Watch.res +0 -102
  59. package/src/Watch.res.mjs +0 -80
  60. package/src/WatcherProbe.res +0 -56
  61. package/src/WatcherProbe.res.mjs +0 -59
  62. package/src/Worker.res +0 -24
  63. package/src/Worker.res.mjs +0 -9
  64. package/tests/BuildClassifierTest.res +0 -133
  65. package/tests/BuildClassifierTest.res.mjs +0 -176
  66. package/tests/CliRunEntryTest.res +0 -57
  67. package/tests/CliRunEntryTest.res.mjs +0 -65
  68. package/tests/CliWatchScopeTest.res +0 -62
  69. package/tests/CliWatchScopeTest.res.mjs +0 -95
  70. package/tests/ComponentMetaTest.res +0 -67
  71. package/tests/ComponentMetaTest.res.mjs +0 -71
  72. package/tests/DiscoveryTest.res +0 -42
  73. package/tests/DiscoveryTest.res.mjs +0 -43
  74. package/tests/DomainDeadCodeTest.res +0 -119
  75. package/tests/DomainDeadCodeTest.res.mjs +0 -158
  76. package/tests/DomainGraphTest.res +0 -448
  77. package/tests/DomainGraphTest.res.mjs +0 -505
  78. package/tests/ExnMessageTest.res +0 -42
  79. package/tests/ExnMessageTest.res.mjs +0 -64
  80. package/tests/FormatterGoldenTest.res +0 -125
  81. package/tests/FormatterGoldenTest.res.mjs +0 -162
  82. package/tests/FormatterVsCodeMessageTest.res +0 -41
  83. package/tests/FormatterVsCodeMessageTest.res.mjs +0 -42
  84. package/tests/PlatformRunnerTest.res +0 -66
  85. package/tests/PlatformRunnerTest.res.mjs +0 -85
  86. package/tests/PlatformScanTest.res +0 -61
  87. package/tests/PlatformScanTest.res.mjs +0 -56
  88. package/tests/RunnerUnitTest.res +0 -219
  89. package/tests/RunnerUnitTest.res.mjs +0 -244
  90. package/tests/WatchDebounceTest.res +0 -106
  91. package/tests/WatchDebounceTest.res.mjs +0 -128
package/src/Cli.res.mjs DELETED
@@ -1,944 +0,0 @@
1
- // Generated by ReScript, PLEASE EDIT WITH CARE
2
-
3
- import * as Nodepath from "node:path";
4
- import * as Nodecrypto from "node:crypto";
5
- import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
6
- import * as Stdlib_JsExn from "@rescript/runtime/lib/es6/Stdlib_JsExn.js";
7
- import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
8
- import * as Primitive_object from "@rescript/runtime/lib/es6/Primitive_object.js";
9
- import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
10
- import * as Watch$ReventlessGwt from "./Watch.res.mjs";
11
- import * as Nodeworker_threads from "node:worker_threads";
12
- import * as Loader$ReventlessGwt from "./Loader.res.mjs";
13
- import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
14
- import * as Worker$ReventlessGwt from "./Worker.res.mjs";
15
- import * as Outcome$ReventlessGwt from "./Outcome.res.mjs";
16
- import * as Collector$ReventlessGwt from "./Collector.res.mjs";
17
- import * as Discovery$ReventlessGwt from "./Discovery.res.mjs";
18
- import * as LocalHost$ReventlessGwt from "./LocalHost.res.mjs";
19
- import * as ExnMessage$ReventlessGwt from "./ExnMessage.res.mjs";
20
- import * as RunnerHook$ReventlessGwt from "./RunnerHook.res.mjs";
21
- import * as DomainGraph$ReventlessGwt from "./DomainGraph.res.mjs";
22
- import * as PackageScan$ReventlessGwt from "./PackageScan.res.mjs";
23
- import * as RunnerTypes$ReventlessGwt from "./RunnerTypes.res.mjs";
24
- import * as Cancellation$ReventlessGwt from "./Cancellation.res.mjs";
25
- import * as FormatterTap$ReventlessGwt from "./FormatterTap.res.mjs";
26
- import * as PlatformScan$ReventlessGwt from "./PlatformScan.res.mjs";
27
- import * as WatcherProbe$ReventlessGwt from "./WatcherProbe.res.mjs";
28
- import * as ComponentScan$ReventlessGwt from "./ComponentScan.res.mjs";
29
- import * as FormatterJson$ReventlessGwt from "./FormatterJson.res.mjs";
30
- import * as DomainDeadCode$ReventlessGwt from "./DomainDeadCode.res.mjs";
31
- import * as FormatterHuman$ReventlessGwt from "./FormatterHuman.res.mjs";
32
- import * as FormatterJunit$ReventlessGwt from "./FormatterJunit.res.mjs";
33
- import * as PlatformRunner$ReventlessGwt from "./PlatformRunner.res.mjs";
34
- import * as ProcessManager$ReventlessGwt from "./ProcessManager.res.mjs";
35
- import * as BuildClassifier$ReventlessGwt from "./BuildClassifier.res.mjs";
36
- import * as FormatterVsCode$ReventlessGwt from "./FormatterVsCode.res.mjs";
37
- import * as Platform_ComponentDefinitionsApi$ReventlessCore from "@reventlessdev/reventless-core/src/admin/Platform_ComponentDefinitionsApi.res.mjs";
38
-
39
- let toolVersion = "0.1.0";
40
-
41
- function sha256(s) {
42
- return Nodecrypto.createHash("sha256").update(s).digest("hex");
43
- }
44
-
45
- let lastDomainHash = {
46
- contents: undefined
47
- };
48
-
49
- function dateNowIso() {
50
- return new Date().toISOString();
51
- }
52
-
53
- function parseFormat(s) {
54
- switch (s) {
55
- case "human" :
56
- return {
57
- TAG: "Ok",
58
- _0: "Human"
59
- };
60
- case "json" :
61
- return {
62
- TAG: "Ok",
63
- _0: "Json"
64
- };
65
- case "junit" :
66
- return {
67
- TAG: "Ok",
68
- _0: "Junit"
69
- };
70
- case "tap" :
71
- return {
72
- TAG: "Ok",
73
- _0: "Tap"
74
- };
75
- case "vscode" :
76
- return {
77
- TAG: "Ok",
78
- _0: "VsCode"
79
- };
80
- default:
81
- return {
82
- TAG: "Error",
83
- _0: "Unknown --format value: " + s
84
- };
85
- }
86
- }
87
-
88
- function defaultRoots() {
89
- return ["."];
90
- }
91
-
92
- function help() {
93
- return `reventless-dev — Reventless dev CLI: GWT runner, domain graph, components, platform runner
94
-
95
- USAGE:
96
- reventless-dev run [--format=<fmt>] [--filter=<id>] [--stream] [--watch] [path...]
97
- reventless-dev discover [--format=vscode] [path...]
98
- reventless-dev watch [--format=<fmt>] [--filter=<id>] [path...]
99
- reventless-dev platform [--format=vscode] [--backend=<b>] [--ui-ports] [path...]
100
- reventless-dev platform --list [path...]
101
-
102
- FORMATS:
103
- human ANSI-coloured terminal output (default)
104
- json Structured JSON envelope (--stream for NDJSON)
105
- tap TAP 14 with YAML diagnostics
106
- junit JUnit XML (single batch)
107
- vscode NDJSON event stream for the VS Code Testing API
108
-
109
- FLAGS:
110
- --filter <id> Restrict execution to tests whose id contains <id>.
111
- Repeatable.
112
- --stream NDJSON streaming (json/vscode)
113
- --watch Re-run on file change
114
- --schema-version <v> Pin a JSON schema version for stable AI prompts
115
- --backend <b> platform: storage backend for the spawned local platform
116
- ("memory" default, or "sqlite:<path>[?reset]")
117
- --ui-ports platform: pin the platform to the fixed default ports
118
- (4000/4001/3001/3002) instead of ephemeral ones, so the
119
- host-shell UI's Vite proxy can reach it
120
- --list platform: list launchable platform packages as NDJSON
121
- ({name, dir} per line) and exit
122
- --help Show this help and exit
123
-
124
- Exit code is 1 if any test failed, 0 otherwise.
125
- `;
126
- }
127
-
128
- function parseArgv(argv) {
129
- let slice = argv.slice(2, argv.length);
130
- let subcommand = "Run";
131
- let format = "Human";
132
- let stream = false;
133
- let watch = false;
134
- let filters = [];
135
- let schemaVersion;
136
- let roots = [];
137
- let backend = "memory";
138
- let uiPorts = false;
139
- let listPlatforms = false;
140
- let error;
141
- let showHelp = false;
142
- let i = 0;
143
- let len = slice.length;
144
- if (len > 0) {
145
- let first = slice[0];
146
- switch (first) {
147
- case "--help" :
148
- case "-h" :
149
- showHelp = true;
150
- break;
151
- case "discover" :
152
- subcommand = "Discover";
153
- format = "VsCode";
154
- i = 1;
155
- break;
156
- case "platform" :
157
- subcommand = "Platform";
158
- i = 1;
159
- break;
160
- case "run" :
161
- subcommand = "Run";
162
- i = 1;
163
- break;
164
- case "watch" :
165
- subcommand = "Watch";
166
- watch = true;
167
- i = 1;
168
- break;
169
- }
170
- }
171
- while (i < len && error === undefined && !showHelp) {
172
- let arg = slice[i];
173
- if (arg === "--help" || arg === "-h") {
174
- showHelp = true;
175
- } else if (arg.startsWith("--format=")) {
176
- let v = arg.slice(9, arg.length);
177
- let f = parseFormat(v);
178
- if (f.TAG === "Ok") {
179
- format = f._0;
180
- } else {
181
- error = f._0;
182
- }
183
- } else if (arg === "--format" && (i + 1 | 0) < len) {
184
- let v$1 = slice[i + 1 | 0];
185
- let f$1 = parseFormat(v$1);
186
- if (f$1.TAG === "Ok") {
187
- format = f$1._0;
188
- } else {
189
- error = f$1._0;
190
- }
191
- i = i + 1 | 0;
192
- } else if (arg.startsWith("--filter=")) {
193
- let v$2 = arg.slice(9, arg.length);
194
- filters = filters.concat([v$2]);
195
- } else if (arg === "--filter" && (i + 1 | 0) < len) {
196
- let v$3 = slice[i + 1 | 0];
197
- filters = filters.concat([v$3]);
198
- i = i + 1 | 0;
199
- } else if (arg === "--stream") {
200
- stream = true;
201
- } else if (arg === "--watch") {
202
- watch = true;
203
- } else if (arg.startsWith("--schema-version=")) {
204
- let v$4 = arg.slice(17, arg.length);
205
- schemaVersion = v$4;
206
- } else if (arg.startsWith("--backend=")) {
207
- backend = arg.slice(10, arg.length);
208
- } else if (arg === "--backend" && (i + 1 | 0) < len) {
209
- backend = slice[i + 1 | 0];
210
- i = i + 1 | 0;
211
- } else if (arg === "--ui-ports") {
212
- uiPorts = true;
213
- } else if (arg === "--list") {
214
- listPlatforms = true;
215
- } else if (arg.startsWith("--")) {
216
- error = "Unknown flag: " + arg;
217
- } else {
218
- roots = roots.concat([arg]);
219
- }
220
- i = i + 1 | 0;
221
- };
222
- if (showHelp) {
223
- return {
224
- TAG: "Error",
225
- _0: `reventless-dev — Reventless dev CLI: GWT runner, domain graph, components, platform runner
226
-
227
- USAGE:
228
- reventless-dev run [--format=<fmt>] [--filter=<id>] [--stream] [--watch] [path...]
229
- reventless-dev discover [--format=vscode] [path...]
230
- reventless-dev watch [--format=<fmt>] [--filter=<id>] [path...]
231
- reventless-dev platform [--format=vscode] [--backend=<b>] [--ui-ports] [path...]
232
- reventless-dev platform --list [path...]
233
-
234
- FORMATS:
235
- human ANSI-coloured terminal output (default)
236
- json Structured JSON envelope (--stream for NDJSON)
237
- tap TAP 14 with YAML diagnostics
238
- junit JUnit XML (single batch)
239
- vscode NDJSON event stream for the VS Code Testing API
240
-
241
- FLAGS:
242
- --filter <id> Restrict execution to tests whose id contains <id>.
243
- Repeatable.
244
- --stream NDJSON streaming (json/vscode)
245
- --watch Re-run on file change
246
- --schema-version <v> Pin a JSON schema version for stable AI prompts
247
- --backend <b> platform: storage backend for the spawned local platform
248
- ("memory" default, or "sqlite:<path>[?reset]")
249
- --ui-ports platform: pin the platform to the fixed default ports
250
- (4000/4001/3001/3002) instead of ephemeral ones, so the
251
- host-shell UI's Vite proxy can reach it
252
- --list platform: list launchable platform packages as NDJSON
253
- ({name, dir} per line) and exit
254
- --help Show this help and exit
255
-
256
- Exit code is 1 if any test failed, 0 otherwise.
257
- `
258
- };
259
- }
260
- let e = error;
261
- if (e !== undefined) {
262
- return {
263
- TAG: "Error",
264
- _0: e + "\n\n" + `reventless-dev — Reventless dev CLI: GWT runner, domain graph, components, platform runner
265
-
266
- USAGE:
267
- reventless-dev run [--format=<fmt>] [--filter=<id>] [--stream] [--watch] [path...]
268
- reventless-dev discover [--format=vscode] [path...]
269
- reventless-dev watch [--format=<fmt>] [--filter=<id>] [path...]
270
- reventless-dev platform [--format=vscode] [--backend=<b>] [--ui-ports] [path...]
271
- reventless-dev platform --list [path...]
272
-
273
- FORMATS:
274
- human ANSI-coloured terminal output (default)
275
- json Structured JSON envelope (--stream for NDJSON)
276
- tap TAP 14 with YAML diagnostics
277
- junit JUnit XML (single batch)
278
- vscode NDJSON event stream for the VS Code Testing API
279
-
280
- FLAGS:
281
- --filter <id> Restrict execution to tests whose id contains <id>.
282
- Repeatable.
283
- --stream NDJSON streaming (json/vscode)
284
- --watch Re-run on file change
285
- --schema-version <v> Pin a JSON schema version for stable AI prompts
286
- --backend <b> platform: storage backend for the spawned local platform
287
- ("memory" default, or "sqlite:<path>[?reset]")
288
- --ui-ports platform: pin the platform to the fixed default ports
289
- (4000/4001/3001/3002) instead of ephemeral ones, so the
290
- host-shell UI's Vite proxy can reach it
291
- --list platform: list launchable platform packages as NDJSON
292
- ({name, dir} per line) and exit
293
- --help Show this help and exit
294
-
295
- Exit code is 1 if any test failed, 0 otherwise.
296
- `
297
- };
298
- } else {
299
- return {
300
- TAG: "Ok",
301
- _0: {
302
- subcommand: subcommand,
303
- format: format,
304
- stream: stream,
305
- watch: watch,
306
- filters: filters,
307
- schemaVersion: schemaVersion,
308
- roots: roots.length === 0 ? ["."] : roots,
309
- backend: backend,
310
- uiPorts: uiPorts,
311
- listPlatforms: listPlatforms,
312
- toolVersion: toolVersion,
313
- paths: undefined
314
- }
315
- };
316
- }
317
- }
318
-
319
- function passesFilter(id, filters) {
320
- if (filters.length === 0) {
321
- return true;
322
- } else {
323
- return filters.some(f => id.includes(f));
324
- }
325
- }
326
-
327
- function raceWithTimeout(body, ms) {
328
- let handleRef = {
329
- contents: undefined
330
- };
331
- let timeout = new Promise((resolve, _reject) => {
332
- handleRef.contents = Primitive_option.some(setTimeout(() => resolve(Outcome$ReventlessGwt.fail({
333
- TAG: "Throw",
334
- error: `timed out after ` + ms.toString() + `ms`,
335
- stack: ""
336
- })), ms));
337
- });
338
- return Promise.race([
339
- body(),
340
- timeout
341
- ]).then(o => {
342
- let h = handleRef.contents;
343
- if (h !== undefined) {
344
- clearTimeout(Primitive_option.valFromOption(h));
345
- }
346
- return Promise.resolve(o);
347
- });
348
- }
349
-
350
- async function runEntry(entry) {
351
- let start = performance.now();
352
- let status = "Pass";
353
- let mismatch;
354
- let match = entry.status;
355
- let exit = 0;
356
- switch (match) {
357
- case "Skipped" :
358
- status = "Skip";
359
- break;
360
- case "Runnable" :
361
- case "Only" :
362
- exit = 1;
363
- break;
364
- }
365
- if (exit === 1) {
366
- try {
367
- let deadline = Stdlib_Option.getOr(entry.timeout, 5000);
368
- let outcome = await raceWithTimeout(entry.body, deadline);
369
- if (outcome.TAG === "Ok") {
370
- status = "Pass";
371
- } else {
372
- status = "Fail";
373
- mismatch = outcome._0;
374
- }
375
- } catch (raw_exn) {
376
- let exn = Primitive_exceptions.internalToException(raw_exn);
377
- status = "Fail";
378
- let err = ExnMessage$ReventlessGwt.extract(exn);
379
- let stack = ExnMessage$ReventlessGwt.stack(exn);
380
- mismatch = {
381
- TAG: "Throw",
382
- error: err,
383
- stack: stack
384
- };
385
- }
386
- }
387
- let durationMs = performance.now() - start;
388
- return {
389
- id: entry.id,
390
- name: entry.name,
391
- describePath: entry.describePath,
392
- status: status,
393
- durationMs: durationMs,
394
- location: entry.location,
395
- slice: entry.slice,
396
- mismatch: mismatch,
397
- skipReason: entry.status === "Skipped" ? "skipped at source" : undefined
398
- };
399
- }
400
-
401
- async function loadAndCollect(path) {
402
- Collector$ReventlessGwt.activate();
403
- RunnerHook$ReventlessGwt.register(Collector$ReventlessGwt.asSink);
404
- Collector$ReventlessGwt.setCurrentFile(path);
405
- try {
406
- await Loader$ReventlessGwt.loadFile(path);
407
- } catch (raw_exn) {
408
- let exn = Primitive_exceptions.internalToException(raw_exn);
409
- let msg = Stdlib_Option.getOr(Stdlib_Option.flatMap(Stdlib_JsExn.fromException(exn), Stdlib_JsExn.message), "import failed");
410
- Collector$ReventlessGwt.push(undefined, undefined, undefined, `<file-load-error>`, () => Promise.resolve(Outcome$ReventlessGwt.fail({
411
- TAG: "Throw",
412
- error: "Failed to load " + path + ": " + msg,
413
- stack: ""
414
- })));
415
- }
416
- let entries = Collector$ReventlessGwt.drain();
417
- Collector$ReventlessGwt.deactivate();
418
- return entries;
419
- }
420
-
421
- async function runFiles(opts, paths, onFileFinished, onTestStart, onTestFinished) {
422
- let startedAt = new Date().toISOString();
423
- let startTime = performance.now();
424
- let files = [];
425
- for (let i = 0, i_finish = paths.length; i < i_finish; ++i) {
426
- let path = paths[i];
427
- if (!Cancellation$ReventlessGwt.isCancelled()) {
428
- let entries = await loadAndCollect(path);
429
- let onlyActive = Collector$ReventlessGwt.hasOnly.contents;
430
- let selected = entries.filter(e => {
431
- let keepByOnly = onlyActive ? e.status === "Only" : true;
432
- let qualifiedId = path + "::" + e.id;
433
- let keepByFilter = passesFilter(e.id, opts.filters) || passesFilter(qualifiedId, opts.filters);
434
- if (keepByOnly) {
435
- return keepByFilter;
436
- } else {
437
- return false;
438
- }
439
- });
440
- let tests = [];
441
- for (let j = 0, j_finish = selected.length; j < j_finish; ++j) {
442
- if (Cancellation$ReventlessGwt.isCancelled()) {
443
- let e = selected[j];
444
- let r_id = e.id;
445
- let r_name = e.name;
446
- let r_describePath = e.describePath;
447
- let r_location = e.location;
448
- let r_slice = e.slice;
449
- let r_skipReason = "cancelled";
450
- let r = {
451
- id: r_id,
452
- name: r_name,
453
- describePath: r_describePath,
454
- status: "Skip",
455
- durationMs: 0.0,
456
- location: r_location,
457
- slice: r_slice,
458
- mismatch: undefined,
459
- skipReason: r_skipReason
460
- };
461
- tests.push(r);
462
- if (onTestFinished !== undefined) {
463
- onTestFinished(path, r);
464
- }
465
- } else {
466
- let entry = selected[j];
467
- if (onTestStart !== undefined) {
468
- onTestStart(path, entry);
469
- }
470
- let r$1 = await runEntry(entry);
471
- tests.push(r$1);
472
- if (onTestFinished !== undefined) {
473
- onTestFinished(path, r$1);
474
- }
475
- }
476
- }
477
- let fr = {
478
- path: path,
479
- tests: tests
480
- };
481
- files.push(fr);
482
- if (onFileFinished !== undefined) {
483
- onFileFinished(fr);
484
- }
485
- }
486
- }
487
- let durationMs = performance.now() - startTime;
488
- let summary = RunnerTypes$ReventlessGwt.summaryOf(files, durationMs, startedAt);
489
- return {
490
- summary: summary,
491
- files: files
492
- };
493
- }
494
-
495
- function emitResult(opts, r) {
496
- let match = opts.format;
497
- switch (match) {
498
- case "Human" :
499
- return FormatterHuman$ReventlessGwt.emit(r);
500
- case "Json" :
501
- if (opts.stream) {
502
- return FormatterJson$ReventlessGwt.streamRunEnd(r);
503
- } else {
504
- return FormatterJson$ReventlessGwt.emit(r, opts.toolVersion, opts.schemaVersion);
505
- }
506
- case "Tap" :
507
- return FormatterTap$ReventlessGwt.emit(r);
508
- case "Junit" :
509
- return FormatterJunit$ReventlessGwt.emit(r);
510
- case "VsCode" :
511
- return FormatterVsCode$ReventlessGwt.runEnd(r.summary);
512
- }
513
- }
514
-
515
- function mergeScope(a, b) {
516
- if (typeof a !== "object") {
517
- return "RunAll";
518
- }
519
- if (typeof b !== "object") {
520
- return "RunAll";
521
- }
522
- let seen = {};
523
- let union = [];
524
- a._0.concat(b._0).forEach(d => {
525
- let match = seen[d];
526
- if (match !== undefined) {
527
- return;
528
- } else {
529
- seen[d] = true;
530
- union.push(d);
531
- return;
532
- }
533
- });
534
- return {
535
- TAG: "RunPackages",
536
- _0: union
537
- };
538
- }
539
-
540
- function pathUnderDir(path, dir) {
541
- return path.startsWith(dir.endsWith("/") ? dir : dir + "/");
542
- }
543
-
544
- function scopeSubset(scope, allPaths) {
545
- if (typeof scope !== "object") {
546
- return allPaths;
547
- }
548
- let dirs = scope._0;
549
- return allPaths.filter(p => dirs.some(d => pathUnderDir(p, d)));
550
- }
551
-
552
- async function runOnce(opts) {
553
- let p = opts.paths;
554
- let paths = p !== undefined ? p : await Discovery$ReventlessGwt.discover(opts.roots);
555
- if (opts.format === "Json" && opts.stream) {
556
- FormatterJson$ReventlessGwt.streamRunStart(opts.toolVersion, new Date().toISOString(), opts.schemaVersion);
557
- }
558
- let match = opts.format;
559
- let match$1 = opts.stream;
560
- let onFileFinished;
561
- onFileFinished = match === "Json" && match$1 ? f => {
562
- f.tests.forEach(FormatterJson$ReventlessGwt.streamTest);
563
- FormatterJson$ReventlessGwt.streamFileFinished(f);
564
- } : undefined;
565
- let onTestStart = opts.format === "VsCode" ? (path, e) => FormatterVsCode$ReventlessGwt.testStart(path + "::" + e.id) : undefined;
566
- let onTestFinished = opts.format === "VsCode" ? (path, t) => {
567
- let id = path + "::" + t.id;
568
- let match = t.status;
569
- switch (match) {
570
- case "Pass" :
571
- return FormatterVsCode$ReventlessGwt.testPass(id, t.durationMs);
572
- case "Fail" :
573
- return FormatterVsCode$ReventlessGwt.testFail(t, id);
574
- case "Skip" :
575
- return FormatterVsCode$ReventlessGwt.testSkip(id, Stdlib_Option.getOr(t.skipReason, "skipped"));
576
- }
577
- } : undefined;
578
- if (opts.format === "Json" && opts.stream) {
579
- paths.forEach(FormatterJson$ReventlessGwt.streamFileStart);
580
- } else if (opts.format === "VsCode") {
581
- FormatterVsCode$ReventlessGwt.runStart(0, opts.filters);
582
- }
583
- let result = await runFiles(opts, paths, onFileFinished, onTestStart, onTestFinished);
584
- emitResult(opts, result);
585
- if (result.summary.failed > 0) {
586
- return 1;
587
- } else {
588
- return 0;
589
- }
590
- }
591
-
592
- async function emitDomainAnalysis(pkgs) {
593
- let plugins = LocalHost$ReventlessGwt.discover(pkgs.map(p => p.dir));
594
- if (plugins.length === 0) {
595
- return;
596
- }
597
- let platformModulePath = LocalHost$ReventlessGwt.resolveLocalPlatform(plugins[0].packageDir);
598
- if (platformModulePath === undefined) {
599
- return;
600
- }
601
- try {
602
- let loaded = await LocalHost$ReventlessGwt.loadGraph(platformModulePath, plugins);
603
- let definitions = loaded.structures.map(param => Platform_ComponentDefinitionsApi$ReventlessCore.encodePluginStructureEntry(param[0], param[1]));
604
- let fingerprint = sha256(JSON.stringify(definitions));
605
- if (Primitive_object.notequal(lastDomainHash.contents, fingerprint)) {
606
- lastDomainHash.contents = fingerprint;
607
- FormatterVsCode$ReventlessGwt.deadCode(DomainDeadCode$ReventlessGwt.analyze(loaded.structures));
608
- FormatterVsCode$ReventlessGwt.graph(DomainGraph$ReventlessGwt.build(loaded.structures));
609
- return FormatterVsCode$ReventlessGwt.definitions(definitions);
610
- } else {
611
- return;
612
- }
613
- } catch (exn) {
614
- return;
615
- }
616
- }
617
-
618
- async function emitDiscovery(paths) {
619
- FormatterVsCode$ReventlessGwt.discoverStart();
620
- let fileTests = [];
621
- for (let i = 0, i_finish = paths.length; i < i_finish; ++i) {
622
- let path = paths[i];
623
- let entries = await loadAndCollect(path);
624
- let tests = entries.map(e => ({
625
- id: e.id,
626
- name: e.name,
627
- describePath: e.describePath,
628
- status: "Skip",
629
- durationMs: 0.0,
630
- location: e.location,
631
- slice: e.slice,
632
- mismatch: undefined,
633
- skipReason: undefined
634
- }));
635
- fileTests.push([
636
- path,
637
- tests
638
- ]);
639
- }
640
- FormatterVsCode$ReventlessGwt.emitDiscoveryItems(fileTests);
641
- let total = Stdlib_Array.reduce(fileTests, 0, (a, param) => a + param[1].length | 0);
642
- let pkgs = PackageScan$ReventlessGwt.scan(paths);
643
- FormatterVsCode$ReventlessGwt.packages(pkgs);
644
- let comps = await ComponentScan$ReventlessGwt.scan(pkgs.map(p => p.dir));
645
- FormatterVsCode$ReventlessGwt.components(comps);
646
- FormatterVsCode$ReventlessGwt.discoverEnd(total);
647
- return await emitDomainAnalysis(pkgs);
648
- }
649
-
650
- async function runDiscover(opts) {
651
- let paths = await Discovery$ReventlessGwt.discover(opts.roots);
652
- await emitDiscovery(paths);
653
- return 0;
654
- }
655
-
656
- function startBuildWatchers(paths) {
657
- Cancellation$ReventlessGwt.onCancel(ProcessManager$ReventlessGwt.killAll);
658
- PackageScan$ReventlessGwt.scan(paths).forEach(pkg => {
659
- if (WatcherProbe$ReventlessGwt.hasLiveWatcher(pkg.dir)) {
660
- return FormatterVsCode$ReventlessGwt.buildExternal(pkg.dir);
661
- }
662
- let feed = BuildClassifier$ReventlessGwt.make(undefined, {
663
- onStart: () => FormatterVsCode$ReventlessGwt.buildStart(pkg.dir),
664
- onOk: ms => FormatterVsCode$ReventlessGwt.buildOk(pkg.dir, ms),
665
- onFail: msg => FormatterVsCode$ReventlessGwt.buildFail(pkg.dir, msg)
666
- });
667
- ProcessManager$ReventlessGwt.spawnWatcher(pkg, (_dir, line) => feed(line));
668
- });
669
- }
670
-
671
- async function runWatch(opts) {
672
- let roots = opts.roots;
673
- let discoveredPaths = {
674
- contents: []
675
- };
676
- if (opts.format === "VsCode") {
677
- let paths = await Discovery$ReventlessGwt.discover(roots);
678
- discoveredPaths.contents = paths;
679
- await emitDiscovery(paths);
680
- startBuildWatchers(paths);
681
- }
682
- let currentWorker = {
683
- contents: undefined
684
- };
685
- Cancellation$ReventlessGwt.onCancel(() => {
686
- let w = currentWorker.contents;
687
- if (w !== undefined) {
688
- Primitive_option.valFromOption(w).terminate();
689
- return;
690
- }
691
- });
692
- let runInWorker = paths => new Promise((resolve, _reject) => {
693
- let w = new Nodeworker_threads.Worker(Worker$ReventlessGwt.runWorkerUrl, {
694
- workerData: {
695
- subcommand: opts.subcommand,
696
- format: opts.format,
697
- stream: opts.stream,
698
- watch: opts.watch,
699
- filters: opts.filters,
700
- schemaVersion: opts.schemaVersion,
701
- roots: opts.roots,
702
- backend: opts.backend,
703
- uiPorts: opts.uiPorts,
704
- listPlatforms: opts.listPlatforms,
705
- toolVersion: opts.toolVersion,
706
- paths: paths
707
- }
708
- });
709
- currentWorker.contents = Primitive_option.some(w);
710
- let settled = {
711
- contents: false
712
- };
713
- let settle = () => {
714
- if (!settled.contents) {
715
- settled.contents = true;
716
- currentWorker.contents = undefined;
717
- return resolve();
718
- }
719
- };
720
- w.on("exit", _code => settle());
721
- w.on("error", e => {
722
- console.error("gwt run worker error:", e);
723
- settle();
724
- });
725
- });
726
- let pathsForScope = scope => {
727
- if (opts.format === "VsCode") {
728
- return scopeSubset(scope, discoveredPaths.contents);
729
- }
730
- };
731
- let runInProgress = {
732
- contents: false
733
- };
734
- let pendingScope = {
735
- contents: undefined
736
- };
737
- let requestRun = async scope => {
738
- if (runInProgress.contents) {
739
- let s = pendingScope.contents;
740
- pendingScope.contents = s !== undefined ? mergeScope(s, scope) : scope;
741
- return;
742
- }
743
- runInProgress.contents = true;
744
- await runInWorker(pathsForScope(scope));
745
- let drain = async () => {
746
- let next = pendingScope.contents;
747
- if (next !== undefined) {
748
- pendingScope.contents = undefined;
749
- await runInWorker(pathsForScope(next));
750
- return await drain();
751
- } else {
752
- runInProgress.contents = false;
753
- return;
754
- }
755
- };
756
- return await drain();
757
- };
758
- await requestRun("RunAll");
759
- let rediscoverAndRun = async () => {
760
- if (opts.format === "VsCode") {
761
- discoveredPaths.contents = await Discovery$ReventlessGwt.discover(roots);
762
- }
763
- await requestRun("RunAll");
764
- };
765
- let rebuilding = {};
766
- let refreshDiscovery = async () => {
767
- let paths = await Discovery$ReventlessGwt.discover(roots);
768
- discoveredPaths.contents = paths;
769
- await emitDiscovery(paths);
770
- startBuildWatchers(paths);
771
- await requestRun("RunAll");
772
- };
773
- let affectedScope = path => {
774
- if (opts.format !== "VsCode") {
775
- return "RunAll";
776
- }
777
- let abs = Nodepath.resolve(path);
778
- let pkg = PackageScan$ReventlessGwt.findOwning(Nodepath.dirname(abs));
779
- if (pkg !== undefined && discoveredPaths.contents.some(p => pathUnderDir(p, pkg.dir))) {
780
- return {
781
- TAG: "RunPackages",
782
- _0: [pkg.dir]
783
- };
784
- } else {
785
- return "RunAll";
786
- }
787
- };
788
- Watch$ReventlessGwt.start(roots, (event, path) => {
789
- if (opts.format === "VsCode" && Watch$ReventlessGwt.isStructuralSource(event, path)) {
790
- let pkg = PackageScan$ReventlessGwt.findOwning(path);
791
- if (pkg !== undefined) {
792
- if (Stdlib_Option.getOr(rebuilding[pkg.dir], false)) {
793
- return;
794
- }
795
- rebuilding[pkg.dir] = true;
796
- let t0 = Date.now();
797
- FormatterVsCode$ReventlessGwt.buildStart(pkg.dir);
798
- let sawError = {
799
- contents: false
800
- };
801
- let feed = BuildClassifier$ReventlessGwt.make(undefined, {
802
- onStart: () => {},
803
- onOk: _ms => {},
804
- onFail: msg => {
805
- sawError.contents = true;
806
- FormatterVsCode$ReventlessGwt.buildFail(pkg.dir, msg);
807
- }
808
- });
809
- return ProcessManager$ReventlessGwt.cleanRebuild(pkg, (_dir, line) => feed(line), ok => {
810
- rebuilding[pkg.dir] = false;
811
- if (ok) {
812
- FormatterVsCode$ReventlessGwt.buildOk(pkg.dir, Date.now() - t0);
813
- } else if (!sawError.contents) {
814
- FormatterVsCode$ReventlessGwt.buildFail(pkg.dir, "clean rebuild failed");
815
- }
816
- rediscoverAndRun();
817
- });
818
- }
819
- requestRun("RunAll");
820
- return;
821
- } else {
822
- if (opts.format === "VsCode" && event === "Add" && path.endsWith(".res")) {
823
- refreshDiscovery();
824
- } else {
825
- requestRun(affectedScope(path));
826
- }
827
- return;
828
- }
829
- });
830
- await new Promise((resolve, _reject) => Cancellation$ReventlessGwt.onCancel(() => resolve()));
831
- return 0;
832
- }
833
-
834
- async function runPlatform(opts) {
835
- let callbacks = opts.format === "VsCode" ? ({
836
- onStart: FormatterVsCode$ReventlessGwt.platformStart,
837
- onReady: FormatterVsCode$ReventlessGwt.platformReady,
838
- onDomainEvent: FormatterVsCode$ReventlessGwt.domainEvent,
839
- onLog: FormatterVsCode$ReventlessGwt.platformLog,
840
- onStop: FormatterVsCode$ReventlessGwt.platformStop
841
- }) : ({
842
- onStart: ($$package, param, domainPort, param$1) => {
843
- console.log(`▶ platform ` + $$package + ` starting (domain http://localhost:` + domainPort.toString() + `)`);
844
- },
845
- onReady: domainEndpoint => {
846
- console.log(`✓ platform ready — ` + domainEndpoint);
847
- },
848
- onDomainEvent: json => {
849
- console.log("· event " + JSON.stringify(json));
850
- },
851
- onLog: line => {
852
- console.log(line);
853
- },
854
- onStop: code => {
855
- console.log(`■ platform stopped (code ` + Stdlib_Option.mapOr(code, "?", c => c.toString()) + `)`);
856
- }
857
- });
858
- return await PlatformRunner$ReventlessGwt.run(opts.roots, opts.backend, opts.uiPorts, callbacks);
859
- }
860
-
861
- async function listPlatforms(opts) {
862
- let pkgs = await PlatformScan$ReventlessGwt.scan(opts.roots);
863
- pkgs.forEach(pkg => {
864
- let obj = Object.fromEntries([
865
- [
866
- "name",
867
- pkg.name
868
- ],
869
- [
870
- "dir",
871
- pkg.dir
872
- ]
873
- ]);
874
- console.log(JSON.stringify(obj));
875
- });
876
- return 0;
877
- }
878
-
879
- async function main() {
880
- Cancellation$ReventlessGwt.install();
881
- let args = process.argv;
882
- let msg = parseArgv(args);
883
- if (msg.TAG === "Ok") {
884
- let opts = msg._0;
885
- if (opts.format === "VsCode") {
886
- FormatterVsCode$ReventlessGwt.hello();
887
- }
888
- let match = opts.subcommand;
889
- switch (match) {
890
- case "Run" :
891
- return await runOnce(opts);
892
- case "Discover" :
893
- return await runDiscover(opts);
894
- case "Watch" :
895
- return await runWatch(opts);
896
- case "Platform" :
897
- if (opts.listPlatforms) {
898
- return await listPlatforms(opts);
899
- } else {
900
- return await runPlatform(opts);
901
- }
902
- }
903
- } else {
904
- console.error(msg._0);
905
- if (args.some(a => a === "--help" ? true : a === "-h")) {
906
- return 0;
907
- } else {
908
- return 2;
909
- }
910
- }
911
- }
912
-
913
- let defaultTimeoutMs = 5000;
914
-
915
- export {
916
- toolVersion,
917
- sha256,
918
- lastDomainHash,
919
- dateNowIso,
920
- parseFormat,
921
- defaultRoots,
922
- help,
923
- parseArgv,
924
- passesFilter,
925
- defaultTimeoutMs,
926
- raceWithTimeout,
927
- runEntry,
928
- loadAndCollect,
929
- runFiles,
930
- emitResult,
931
- mergeScope,
932
- pathUnderDir,
933
- scopeSubset,
934
- runOnce,
935
- emitDomainAnalysis,
936
- emitDiscovery,
937
- runDiscover,
938
- startBuildWatchers,
939
- runWatch,
940
- runPlatform,
941
- listPlatforms,
942
- main,
943
- }
944
- /* node:path Not a pure module */