automategraph 1.5.1 → 1.5.3

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 (88) hide show
  1. package/CHANGELOG.md +18 -5
  2. package/UPGRADE-PROPOSAL.md +141 -0
  3. package/docs/diagrams/c19-resilience-scenario.md +61 -0
  4. package/docs/diagrams/c19-resilience-scenario.mmd +28 -0
  5. package/docs/diagrams/c19-resilience-scenario.svg +181 -0
  6. package/examples/README.md +206 -0
  7. package/examples/branching-edges.ts +192 -0
  8. package/examples/branching-graph.ts +333 -0
  9. package/examples/branching-router.ts +475 -0
  10. package/examples/json-graph.ts +231 -0
  11. package/examples/json-scripts.ts +152 -0
  12. package/examples/order-flow.functions.cjs +32 -0
  13. package/examples/order-flow.graph.json +27 -0
  14. package/examples/order-flow.scripted.graph.json +68 -0
  15. package/js/examples/branching-edges.js +133 -0
  16. package/js/examples/branching-edges.js.map +1 -0
  17. package/js/examples/branching-graph.js +232 -0
  18. package/js/examples/branching-graph.js.map +1 -0
  19. package/js/examples/branching-router.js +305 -0
  20. package/js/examples/branching-router.js.map +1 -0
  21. package/js/examples/json-graph.js +197 -0
  22. package/js/examples/json-graph.js.map +1 -0
  23. package/js/examples/json-scripts.js +131 -0
  24. package/js/examples/json-scripts.js.map +1 -0
  25. package/js/tests/async.test.js +592 -0
  26. package/js/tests/async.test.js.map +1 -0
  27. package/js/tests/complex.test.js +972 -0
  28. package/js/tests/complex.test.js.map +1 -0
  29. package/js/tests/conformance.test.js +365 -0
  30. package/js/tests/conformance.test.js.map +1 -0
  31. package/js/tests/edges.test.js +702 -0
  32. package/js/tests/edges.test.js.map +1 -0
  33. package/js/tests/graphjson.test.js +504 -0
  34. package/js/tests/graphjson.test.js.map +1 -0
  35. package/js/tests/harness.js +192 -0
  36. package/js/tests/harness.js.map +1 -0
  37. package/js/tests/helpers.js +136 -0
  38. package/js/tests/helpers.js.map +1 -0
  39. package/js/tests/lint.test.js +317 -0
  40. package/js/tests/lint.test.js.map +1 -0
  41. package/js/tests/registry.test.js +705 -0
  42. package/js/tests/registry.test.js.map +1 -0
  43. package/js/tests/report.js +422 -0
  44. package/js/tests/report.js.map +1 -0
  45. package/js/tests/runner.js +67 -0
  46. package/js/tests/runner.js.map +1 -0
  47. package/js/tests/scripts.test.js +552 -0
  48. package/js/tests/scripts.test.js.map +1 -0
  49. package/js/tests/unit.test.js +1239 -0
  50. package/js/tests/unit.test.js.map +1 -0
  51. package/js/tests/upgrade.test.js +618 -0
  52. package/js/tests/upgrade.test.js.map +1 -0
  53. package/package.json +2 -9
  54. package/report/index.html +3727 -0
  55. package/report/report.json +3053 -0
  56. package/tests/async.test.ts +668 -0
  57. package/tests/complex.test.ts +1123 -0
  58. package/tests/conformance.test.ts +442 -0
  59. package/tests/edges.test.ts +848 -0
  60. package/tests/fixtures/scripts/bad-registration.cjs +4 -0
  61. package/tests/fixtures/scripts/broken.cjs +2 -0
  62. package/tests/fixtures/scripts/cjs-default.js +4 -0
  63. package/tests/fixtures/scripts/collide-a.cjs +4 -0
  64. package/tests/fixtures/scripts/collide-b.cjs +4 -0
  65. package/tests/fixtures/scripts/empty.cjs +2 -0
  66. package/tests/fixtures/scripts/esm-functions.mjs +10 -0
  67. package/tests/fixtures/scripts/esm-syntax.js +3 -0
  68. package/tests/fixtures/scripts/global-channel.cjs +6 -0
  69. package/tests/fixtures/scripts/global-channel.mjs +7 -0
  70. package/tests/fixtures/scripts/mismatch.cjs +4 -0
  71. package/tests/fixtures/scripts/needs-sibling.cjs +7 -0
  72. package/tests/fixtures/scripts/order.cjs +14 -0
  73. package/tests/fixtures/scripts/sibling-helper.cjs +3 -0
  74. package/tests/fixtures/scripts/throwing-global.mjs +6 -0
  75. package/tests/graphjson.test.ts +737 -0
  76. package/tests/harness.ts +291 -0
  77. package/tests/helpers.ts +216 -0
  78. package/tests/lint.test.ts +381 -0
  79. package/tests/registry.test.ts +1134 -0
  80. package/tests/report.ts +452 -0
  81. package/tests/runner.ts +58 -0
  82. package/tests/scripts.test.ts +970 -0
  83. package/tests/unit.test.ts +1192 -0
  84. package/tests/upgrade.test.ts +725 -0
  85. package/tools/server.mjs +152 -0
  86. package/tsconfig.browser.json +19 -0
  87. package/tsconfig.json +18 -0
  88. package/tsconfig.publish.json +13 -0
@@ -0,0 +1,152 @@
1
+ /* ============================================================
2
+ * Static report server + auto-refresh
3
+ * ------------------------------------------------------------
4
+ * Serves the workspace so the generated report can be viewed in
5
+ * a browser (and in the Arena live preview). Binds 0.0.0.0 so the
6
+ * preview proxy can reach it. No external dependencies.
7
+ *
8
+ * node tools/server.mjs [port]
9
+ *
10
+ * Routes
11
+ * / -> redirect to /report/index.html
12
+ * /report/index.html -> dashboard (with injected auto-reload)
13
+ * /api/version -> JSON { version, csv } fingerprint of results
14
+ * /api/report.json -> raw machine-readable results
15
+ * /run -> re-runs the suite (tsc + runner) and refreshes
16
+ * ============================================================ */
17
+
18
+ import { createServer } from "node:http";
19
+ import { readFile, stat } from "node:fs/promises";
20
+ import { spawn } from "node:child_process";
21
+ import path from "node:path";
22
+ import { fileURLToPath } from "node:url";
23
+
24
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
25
+ const ROOT = path.resolve(__dirname, "..");
26
+ const PORT = Number(process.argv[2] ?? 4173);
27
+ const HOST = "0.0.0.0";
28
+
29
+ const MIME = {
30
+ ".html": "text/html; charset=utf-8",
31
+ ".json": "application/json; charset=utf-8",
32
+ ".js": "text/javascript; charset=utf-8",
33
+ ".css": "text/css; charset=utf-8",
34
+ ".ts": "text/plain; charset=utf-8",
35
+ ".map": "application/json; charset=utf-8",
36
+ ".svg": "image/svg+xml",
37
+ ".ico": "image/x-icon"
38
+ };
39
+
40
+ async function fingerprint() {
41
+ try {
42
+ const info = await stat(path.join(ROOT, "report", "report.json"));
43
+ const data = JSON.parse(await readFile(path.join(ROOT, "report", "report.json"), "utf8"));
44
+ return {
45
+ version: `${info.mtimeMs}-${data.totals?.passed ?? 0}-${data.totals?.failed ?? 0}`,
46
+ summary: {
47
+ total: data.totals?.total ?? 0,
48
+ passed: data.totals?.passed ?? 0,
49
+ failed: data.totals?.failed ?? 0,
50
+ durationMs: data.durationMs ?? 0,
51
+ generatedAt: data.generatedAt ?? null
52
+ }
53
+ };
54
+ } catch {
55
+ return { version: "missing", summary: null };
56
+ }
57
+ }
58
+
59
+ const RELOAD_SNIPPET = `
60
+ <script>
61
+ (function () {
62
+ var current = null;
63
+ async function poll() {
64
+ try {
65
+ var response = await fetch("/api/version", { cache: "no-store" });
66
+ var data = await response.json();
67
+ if (current === null) current = data.version;
68
+ else if (data.version !== current) location.reload();
69
+ } catch (_) { /* ignore */ }
70
+ }
71
+ setInterval(poll, 2000);
72
+ poll();
73
+ })();
74
+ </script>
75
+ `;
76
+
77
+ function rerunSuite() {
78
+ return new Promise(resolve => {
79
+ const tsc = spawn(path.join(ROOT, "node_modules", ".bin", "tsc"), ["-p", "tsconfig.json"], { cwd: ROOT });
80
+ tsc.on("close", () => {
81
+ const runner = spawn(process.execPath, [path.join(ROOT, "js", "tests", "runner.js")], { cwd: ROOT });
82
+ let output = "";
83
+ runner.stdout.on("data", chunk => { output += chunk.toString(); });
84
+ runner.stderr.on("data", chunk => { output += chunk.toString(); });
85
+ runner.on("close", code => resolve({ code, output }));
86
+ });
87
+ });
88
+ }
89
+
90
+ const server = createServer(async (request, response) => {
91
+ const url = new URL(request.url ?? "/", `http://${request.headers.host ?? "localhost"}`);
92
+ let pathname = decodeURIComponent(url.pathname);
93
+
94
+ if (pathname === "/" ) {
95
+ response.writeHead(302, { Location: "/report/index.html" });
96
+ response.end();
97
+ return;
98
+ }
99
+
100
+ if (pathname === "/api/version") {
101
+ const payload = await fingerprint();
102
+ response.writeHead(200, { "Content-Type": MIME[".json"], "Cache-Control": "no-store" });
103
+ response.end(JSON.stringify(payload));
104
+ return;
105
+ }
106
+
107
+ if (pathname === "/api/report.json") {
108
+ pathname = "/report/report.json";
109
+ }
110
+
111
+ if (pathname === "/run") {
112
+ const result = await rerunSuite();
113
+ response.writeHead(200, { "Content-Type": MIME[".json"], "Cache-Control": "no-store" });
114
+ response.end(JSON.stringify({ exitCode: result.code, tail: result.output.split("\n").slice(-14).join("\n") }));
115
+ return;
116
+ }
117
+
118
+ const filePath = path.join(ROOT, pathname);
119
+
120
+ if (!filePath.startsWith(ROOT)) {
121
+ response.writeHead(403);
122
+ response.end("forbidden");
123
+ return;
124
+ }
125
+
126
+ try {
127
+ let body = await readFile(filePath);
128
+
129
+ if (pathname.endsWith(".html")) {
130
+ const html = body.toString("utf8");
131
+ body = Buffer.from(html.includes("</body>")
132
+ ? html.replace("</body>", `${RELOAD_SNIPPET}</body>`)
133
+ : html + RELOAD_SNIPPET);
134
+ }
135
+
136
+ const extension = path.extname(filePath);
137
+ response.writeHead(200, {
138
+ "Content-Type": MIME[extension] ?? "application/octet-stream",
139
+ "Cache-Control": "no-store"
140
+ });
141
+ response.end(body);
142
+ } catch {
143
+ response.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
144
+ response.end("404 not found");
145
+ }
146
+ });
147
+
148
+ server.listen(PORT, HOST, () => {
149
+ console.log(`AutomateGraph report server listening on http://${HOST}:${PORT}`);
150
+ console.log(`Dashboard: http://localhost:${PORT}/report/index.html`);
151
+ console.log("Re-run endpoint: POST/GET /run (recompiles and re-executes all 120 tests)");
152
+ });
@@ -0,0 +1,19 @@
1
+ {
2
+ /* Isomorphic proof: the engine core must compile with DOM-only libs and
3
+ NO Node types. If any Node-specific API sneaks in, this build fails. */
4
+ "compilerOptions": {
5
+ "target": "ES2022",
6
+ "module": "ESNext",
7
+ "moduleResolution": "bundler",
8
+ "lib": ["ES2022", "DOM"],
9
+ "types": [],
10
+ "noEmit": true,
11
+ "strict": true,
12
+ "skipLibCheck": true,
13
+ "forceConsistentCasingInFileNames": true
14
+ },
15
+ /* Everything isomorphic. src/node/** is Node-only by definition and is
16
+ deliberately outside this guard (the two-step script loader lives there). */
17
+ "include": ["src/**/*.ts"],
18
+ "exclude": ["src/node/**/*.ts"]
19
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "CommonJS",
5
+ "moduleResolution": "node",
6
+ "lib": ["ES2022", "DOM"],
7
+ "types": ["node"],
8
+ "outDir": "js",
9
+ "rootDir": ".",
10
+ "strict": true,
11
+ "esModuleInterop": true,
12
+ "skipLibCheck": true,
13
+ "forceConsistentCasingInFileNames": true,
14
+ "declaration": false,
15
+ "sourceMap": true
16
+ },
17
+ "include": ["src/**/*.ts", "tests/**/*.ts", "examples/**/*.ts"]
18
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ /* Publishing build: emits JavaScript + .d.ts + declaration maps for the
3
+ library sources only (tests, examples and tools are not shipped).
4
+ Consumer-facing types live next to the emitted JS in js/src/. */
5
+ "extends": "./tsconfig.json",
6
+ "compilerOptions": {
7
+ "declaration": true,
8
+ "declarationMap": true,
9
+ "rootDir": ".",
10
+ "outDir": "js"
11
+ },
12
+ "include": ["src/**/*.ts"]
13
+ }