@omni-oss/task-bench 0.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +328 -0
- package/dist/bench/index.d.ts +82 -0
- package/dist/bench/index.d.ts.map +1 -0
- package/dist/bench/install.d.ts +5 -0
- package/dist/bench/install.d.ts.map +1 -0
- package/dist/bench/report.d.ts +9 -0
- package/dist/bench/report.d.ts.map +1 -0
- package/dist/bench/stats.d.ts +12 -0
- package/dist/bench/stats.d.ts.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/config.d.ts +91 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/generate/index.d.ts +19 -0
- package/dist/generate/index.d.ts.map +1 -0
- package/dist/generate/templates.d.ts +20 -0
- package/dist/generate/templates.d.ts.map +1 -0
- package/dist/graph.d.ts +21 -0
- package/dist/graph.d.ts.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +2 -0
- package/dist/src-D3XyMXAu.mjs +1167 -0
- package/dist/suite/index.d.ts +49 -0
- package/dist/suite/index.d.ts.map +1 -0
- package/dist/suite/preset.d.ts +93 -0
- package/dist/suite/preset.d.ts.map +1 -0
- package/dist/suite/report.d.ts +7 -0
- package/dist/suite/report.d.ts.map +1 -0
- package/dist/task-bench-cli.mjs +107 -0
- package/dist/tools/index.d.ts +18 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/moon.d.ts +10 -0
- package/dist/tools/moon.d.ts.map +1 -0
- package/dist/tools/nx.d.ts +7 -0
- package/dist/tools/nx.d.ts.map +1 -0
- package/dist/tools/omni.d.ts +7 -0
- package/dist/tools/omni.d.ts.map +1 -0
- package/dist/tools/turbo.d.ts +5 -0
- package/dist/tools/turbo.d.ts.map +1 -0
- package/dist/tools/types.d.ts +77 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/package.json +41 -0
- package/project.omni.yaml +33 -0
- package/src/bench/index.ts +323 -0
- package/src/bench/install.ts +12 -0
- package/src/bench/report.ts +142 -0
- package/src/bench/stats.spec.ts +35 -0
- package/src/bench/stats.ts +38 -0
- package/src/cli/index.ts +410 -0
- package/src/config.ts +138 -0
- package/src/generate/index.ts +215 -0
- package/src/generate/templates.ts +87 -0
- package/src/graph.spec.ts +119 -0
- package/src/graph.ts +120 -0
- package/src/index.ts +31 -0
- package/src/suite/index.ts +113 -0
- package/src/suite/preset.spec.ts +95 -0
- package/src/suite/preset.ts +253 -0
- package/src/suite/report.ts +135 -0
- package/src/tools/adapters.spec.ts +95 -0
- package/src/tools/config.spec.ts +73 -0
- package/src/tools/index.ts +76 -0
- package/src/tools/moon.ts +106 -0
- package/src/tools/nx.ts +106 -0
- package/src/tools/omni.ts +96 -0
- package/src/tools/turbo.ts +78 -0
- package/src/tools/types.ts +116 -0
- package/tsconfig.json +4 -0
- package/tsconfig.project.json +6 -0
- package/tsconfig.types.json +4 -0
- package/vite.config.ts +29 -0
- package/vitest.config.unit.ts +13 -0
package/README.md
ADDED
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
# @omni-oss/task-bench
|
|
2
|
+
|
|
3
|
+
Generate configurable, minimal test workspaces and benchmark **task-execution
|
|
4
|
+
overhead** across [omni](https://github.com/omni-oss/omni),
|
|
5
|
+
[Turborepo](https://turbo.build), [Nx](https://nx.dev), and
|
|
6
|
+
[moonrepo](https://moonrepo.dev).
|
|
7
|
+
|
|
8
|
+
The goal is to isolate the cost of **project discovery** and **task caching**
|
|
9
|
+
rather than the tasks themselves. Every generated task is fast, deterministic,
|
|
10
|
+
and produces real output (logs + files) so each runner's cache and log-capture
|
|
11
|
+
machinery is exercised. The four runners are configured as equivalently as
|
|
12
|
+
possible from a single source of truth.
|
|
13
|
+
|
|
14
|
+
## How it works
|
|
15
|
+
|
|
16
|
+
For a given config the harness generates one workspace on disk containing:
|
|
17
|
+
|
|
18
|
+
- `packages/<prefix><n>/` — minimal JS projects, each with:
|
|
19
|
+
- `package.json` (scripts + `workspace:*` deps encoding the project graph),
|
|
20
|
+
- `src/index.js` (a cache input),
|
|
21
|
+
- `task.mjs` (the shared, deterministic task runner),
|
|
22
|
+
- `project.omni.yaml` (omni), `project.json` (nx), and `moon.yml` (moon).
|
|
23
|
+
- Root `workspace.omni.yaml`, `turbo.json`, `nx.json`, and `.moon/*.yml`
|
|
24
|
+
describing the same task graph (`tN` depends on `t(N-1)` and/or `^tN`) with
|
|
25
|
+
identical inputs (`package.json`, `task.mjs`, `src/**`) and outputs
|
|
26
|
+
(`dist/tN.*`). The workspace is also `git init`-ed and committed, which moon
|
|
27
|
+
requires to enable its cache (and is harmless/realistic for the others).
|
|
28
|
+
|
|
29
|
+
It then benchmarks each enabled tool in two scenarios:
|
|
30
|
+
|
|
31
|
+
- **cold** — caches + outputs wiped before each run (discovery + full exec).
|
|
32
|
+
- **warm** — caches primed, so every task should be a cache hit. This is the
|
|
33
|
+
key metric for discovery + cache-restore overhead.
|
|
34
|
+
|
|
35
|
+
### Fairness & correctness
|
|
36
|
+
|
|
37
|
+
- **Verified cache hits.** Each task appends one line to an out-of-tree log
|
|
38
|
+
*only when it actually executes* (cache hits skip the process entirely).
|
|
39
|
+
The harness counts these to report a real, tool-agnostic cache-hit rate per
|
|
40
|
+
run, so "warm == all cached" is verified rather than assumed. A warm run that
|
|
41
|
+
is not 100% cached is flagged in the report. (Turbo's strict env mode is
|
|
42
|
+
handled via `globalPassThroughEnv` so the marker survives without affecting
|
|
43
|
+
cache keys.)
|
|
44
|
+
- **Concurrency parity.** The same max-parallelism is passed to every runner
|
|
45
|
+
(`omni -c`, `turbo --concurrency`, `nx --parallel`); defaults to the CPU
|
|
46
|
+
count. Use `--concurrency` to pin it.
|
|
47
|
+
- **Daemon handling.** By default each tool is allowed to use its persistent
|
|
48
|
+
daemon (Turbo's `turbod`, the Nx daemon) so warm runs reflect each tool's
|
|
49
|
+
best incremental performance; the daemon is warmed by an unmeasured prime run
|
|
50
|
+
and left alive across warm runs. Cold runs deliberately tear the daemon down
|
|
51
|
+
(and clear caches) so they include cold-start cost. Daemons are always
|
|
52
|
+
stopped as cleanup afterwards so nothing leaks. Pass `--no-daemon` to disable
|
|
53
|
+
daemons entirely (Turbo `--no-daemon`, `NX_DAEMON=false`); omni and moon have
|
|
54
|
+
no daemon.
|
|
55
|
+
- **Statistics.** Reports median ± standard deviation; full per-run samples
|
|
56
|
+
(duration, exit code, executed-task count) are written to the JSON output.
|
|
57
|
+
|
|
58
|
+
## CLI
|
|
59
|
+
|
|
60
|
+
```sh
|
|
61
|
+
# Generate a workspace only.
|
|
62
|
+
task-bench generate -o /tmp/bench --projects 200 --tasks 4 --strategy layered
|
|
63
|
+
|
|
64
|
+
# Generate, `bun install`, benchmark, and print a report.
|
|
65
|
+
task-bench bench -o /tmp/bench --projects 200 --tasks 4 \
|
|
66
|
+
--strategy random --edge-probability 0.3 \
|
|
67
|
+
--cold-runs 3 --warm-runs 5 --json results.json
|
|
68
|
+
|
|
69
|
+
# Benchmark an already-generated workspace.
|
|
70
|
+
task-bench run -d /tmp/bench --tools omni,turbo --task t3
|
|
71
|
+
|
|
72
|
+
# Run a whole preset of scenarios and summarize (see "Comprehensive suite").
|
|
73
|
+
task-bench suite --preset full --json suite.json --md suite.md
|
|
74
|
+
|
|
75
|
+
# Resolve a config and print it (no side effects).
|
|
76
|
+
task-bench inspect --projects 50 --strategy chain
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Key options
|
|
80
|
+
|
|
81
|
+
| Option | Description |
|
|
82
|
+
| --- | --- |
|
|
83
|
+
| `-o, --out <dir>` | Root dir to generate the workspace into. |
|
|
84
|
+
| `--projects <n>` | Number of projects. |
|
|
85
|
+
| `--tasks <n>` | Tasks per project (`t0..tN-1`). |
|
|
86
|
+
| `--strategy <s>` | `isolated`, `chain`, `fan-out`, `layered`, or `random`. |
|
|
87
|
+
| `--layers <n>` | Layers for the `layered` strategy. |
|
|
88
|
+
| `--fanout <n>` | Max upstream deps per project. |
|
|
89
|
+
| `--edge-probability <p>` | Edge probability for the `random` strategy. |
|
|
90
|
+
| `--log-lines <n>` | Log lines printed per task. |
|
|
91
|
+
| `--work <n>` | CPU work iterations per task. |
|
|
92
|
+
| `--output-files <n>` | Output files written per task. |
|
|
93
|
+
| `--tools <list>` | Comma-separated `omni,turbo,nx,moon`. |
|
|
94
|
+
| `--turbo-version` / `--nx-version` / `--moon-version` / `--bun-version` | Pin the version of each tool to install. |
|
|
95
|
+
| `--concurrency <n>` | Max parallel tasks, applied identically to every runner (default: CPU count). |
|
|
96
|
+
| `--no-daemon` | Disable each tool's persistent daemon (Turbo, Nx). |
|
|
97
|
+
| `--no-chain` / `--no-fan-upstream` | Disable intra/inter-project task deps. |
|
|
98
|
+
| `--config <file>` | JSON config to use as a base for overrides. |
|
|
99
|
+
|
|
100
|
+
## Library
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
import { generateWorkspace, runBenchmark, formatReport } from "@omni-oss/task-bench";
|
|
104
|
+
|
|
105
|
+
await generateWorkspace("/tmp/bench", {
|
|
106
|
+
projects: 100,
|
|
107
|
+
tasksPerProject: 3,
|
|
108
|
+
dependency: { strategy: "layered", layers: 6, fanout: 3 },
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
const result = await runBenchmark("/tmp/bench", { warmRuns: 5 });
|
|
112
|
+
console.log(formatReport(result));
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Comprehensive benchmark suite
|
|
116
|
+
|
|
117
|
+
The `suite` command runs a **preset of scenarios** end-to-end (generate →
|
|
118
|
+
install → benchmark each) and summarizes them into a combined report, with
|
|
119
|
+
`--json` and/or `--md` output.
|
|
120
|
+
|
|
121
|
+
```sh
|
|
122
|
+
# List the built-in presets.
|
|
123
|
+
task-bench suite --list
|
|
124
|
+
# quick | shapes | scale | density | daemon | full
|
|
125
|
+
|
|
126
|
+
# Run a built-in preset and write both machine- and human-readable reports.
|
|
127
|
+
task-bench suite --preset full --json suite.json --md suite.md
|
|
128
|
+
|
|
129
|
+
# Override run parameters for every scenario in the preset.
|
|
130
|
+
task-bench suite --preset scale --cold-runs 3 --warm-runs 5 --concurrency 8
|
|
131
|
+
|
|
132
|
+
# Run only two tools, and keep the generated workspaces around.
|
|
133
|
+
task-bench suite --preset shapes --tools omni,turbo --keep -o /tmp/suite
|
|
134
|
+
|
|
135
|
+
# Run a custom scenario matrix from a JSON file.
|
|
136
|
+
task-bench suite --file my-suite.json --md report.md
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Built-in presets: **`quick`** (tiny smoke test), **`shapes`** (dependency-graph
|
|
140
|
+
shapes at fixed scale), **`scale`** (50–600 projects), **`density`** (tasks per
|
|
141
|
+
project), **`daemon`** (daemon on vs off), and **`full`** (shapes + scale +
|
|
142
|
+
density). A custom preset file looks like:
|
|
143
|
+
|
|
144
|
+
```jsonc
|
|
145
|
+
{
|
|
146
|
+
"name": "my sweep",
|
|
147
|
+
"defaults": {
|
|
148
|
+
"config": { "tasksPerProject": 3, "dependency": { "strategy": "layered" } },
|
|
149
|
+
"run": { "concurrency": 8, "coldRuns": 2, "warmRuns": 3 }
|
|
150
|
+
},
|
|
151
|
+
"scenarios": [
|
|
152
|
+
{ "name": "small", "config": { "projects": 50 } },
|
|
153
|
+
{ "name": "large", "config": { "projects": 500 } },
|
|
154
|
+
{ "name": "large-nodaemon", "config": { "projects": 500 }, "run": { "daemon": false } }
|
|
155
|
+
]
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
The Markdown report contains two summary matrices (warm + cold median per tool
|
|
160
|
+
per scenario) followed by the detailed per-scenario tables; the JSON contains
|
|
161
|
+
the full resolved config, run options, and per-run samples for every scenario.
|
|
162
|
+
|
|
163
|
+
### Scripting it yourself
|
|
164
|
+
|
|
165
|
+
If you prefer explicit shell control, the equivalent manual loop is:
|
|
166
|
+
|
|
167
|
+
````bash
|
|
168
|
+
#!/usr/bin/env bash
|
|
169
|
+
set -euo pipefail
|
|
170
|
+
|
|
171
|
+
# Use the built CLI (`task-bench`) or the dev entry as below.
|
|
172
|
+
BENCH="bun scripts/task-bench/src/cli/index.ts"
|
|
173
|
+
OUT=/tmp/task-bench-suite
|
|
174
|
+
RESULTS="$OUT/results"
|
|
175
|
+
SUITE="$OUT/SUITE.md"
|
|
176
|
+
mkdir -p "$RESULTS"
|
|
177
|
+
: > "$SUITE"
|
|
178
|
+
|
|
179
|
+
run() { # run <label> <bench|run> <args...>
|
|
180
|
+
local label="$1"; shift
|
|
181
|
+
echo "### $label" | tee -a "$SUITE"
|
|
182
|
+
echo '```' >> "$SUITE"
|
|
183
|
+
$BENCH "$@" --json "$RESULTS/$label.json" 2>/dev/null | tee -a "$SUITE"
|
|
184
|
+
echo '```' >> "$SUITE"
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
# 1) Dependency-shape sweep (fixed scale): how graph shape affects overhead.
|
|
188
|
+
for strat in isolated chain fan-out layered random; do
|
|
189
|
+
run "shape-$strat" bench -o "$OUT/shape-$strat" \
|
|
190
|
+
--projects 120 --tasks 3 --strategy "$strat" \
|
|
191
|
+
--concurrency 8 --cold-runs 2 --warm-runs 3
|
|
192
|
+
done
|
|
193
|
+
|
|
194
|
+
# 2) Scale sweep (layered graph): how overhead grows with graph size.
|
|
195
|
+
for n in 50 150 300 600; do
|
|
196
|
+
run "scale-$n" bench -o "$OUT/scale-$n" \
|
|
197
|
+
--projects "$n" --tasks 3 --strategy layered --layers 8 \
|
|
198
|
+
--concurrency 8 --cold-runs 2 --warm-runs 3
|
|
199
|
+
done
|
|
200
|
+
|
|
201
|
+
# 3) Task-density sweep (fixed project count).
|
|
202
|
+
for t in 2 5 10; do
|
|
203
|
+
run "density-$t" bench -o "$OUT/density-$t" \
|
|
204
|
+
--projects 120 --tasks "$t" --strategy layered \
|
|
205
|
+
--concurrency 8 --cold-runs 2 --warm-runs 3
|
|
206
|
+
done
|
|
207
|
+
|
|
208
|
+
# 4) Daemon on vs off (reuse one installed workspace).
|
|
209
|
+
run "daemon-on" bench -o "$OUT/daemon" --projects 200 --tasks 3 \
|
|
210
|
+
--strategy layered --concurrency 8 --cold-runs 2 --warm-runs 3
|
|
211
|
+
run "daemon-off" run -d "$OUT/daemon" --no-daemon \
|
|
212
|
+
--concurrency 8 --cold-runs 2 --warm-runs 3
|
|
213
|
+
|
|
214
|
+
echo "Suite written to $SUITE ; per-scenario JSON in $RESULTS"
|
|
215
|
+
# rm -rf "$OUT" # uncomment to clean up workspaces afterwards
|
|
216
|
+
````
|
|
217
|
+
|
|
218
|
+
Each JSON result contains per-run samples (`durationMs`, `exitCode`,
|
|
219
|
+
`executed`), the verified `taskGraphSize`, and `stats` (min/max/mean/median/
|
|
220
|
+
stddev) for both scenarios, so you can post-process or chart them however you
|
|
221
|
+
like.
|
|
222
|
+
|
|
223
|
+
### Sample results
|
|
224
|
+
|
|
225
|
+
Collected on one machine (Linux, 8-way concurrency, 3 tasks/project, layered
|
|
226
|
+
unless noted; `warm` = verified 100% cache hit, the discovery + cache-restore
|
|
227
|
+
overhead metric). Absolute numbers are hardware-dependent — read the *ratios*.
|
|
228
|
+
|
|
229
|
+
**Four-runner snapshot** (40 projects × 3 tasks, 120 nodes, layered):
|
|
230
|
+
|
|
231
|
+
| tool | warm | cold |
|
|
232
|
+
| --- | --- | --- |
|
|
233
|
+
| omni | **76ms** | 990ms |
|
|
234
|
+
| turbo | 135ms | 915ms |
|
|
235
|
+
| nx | 434ms | 2.27s |
|
|
236
|
+
| moon | 448ms | 1.45s |
|
|
237
|
+
|
|
238
|
+
The larger sweeps below predate the moon addition (omni/turbo/nx only); rerun
|
|
239
|
+
`task-bench suite --preset full` to regenerate them with all four runners.
|
|
240
|
+
|
|
241
|
+
<!-- SUITE_RESULTS -->
|
|
242
|
+
|
|
243
|
+
**Dependency-shape sweep** (120 projects × 3 tasks, 360 task-graph nodes):
|
|
244
|
+
|
|
245
|
+
| strategy | omni warm | turbo warm | nx warm | omni cold | turbo cold | nx cold |
|
|
246
|
+
| --- | --- | --- | --- | --- | --- | --- |
|
|
247
|
+
| isolated | 292ms | **239ms** | 644ms | 3.27s | 2.52s | 8.22s |
|
|
248
|
+
| chain | 403ms | **231ms** | 1.09s | 5.36s | 4.91s | 9.09s |
|
|
249
|
+
| fan-out | 304ms | **246ms** | 678ms | 3.46s | 2.61s | 8.79s |
|
|
250
|
+
| layered | 252ms | **246ms** | 678ms | 3.21s | 2.63s | 8.71s |
|
|
251
|
+
| random | 284ms | **254ms** | 797ms | 3.59s | 3.12s | 8.72s |
|
|
252
|
+
|
|
253
|
+
**Scale sweep** (layered, 3 tasks):
|
|
254
|
+
|
|
255
|
+
| projects (nodes) | omni warm | turbo warm | nx warm | omni cold | turbo cold | nx cold |
|
|
256
|
+
| --- | --- | --- | --- | --- | --- | --- |
|
|
257
|
+
| 50 (150) | **106ms** | 134ms | 478ms | 1.34s | 1.14s | 2.81s |
|
|
258
|
+
| 150 (450) | 295ms | **287ms** | 764ms | 4.05s | 3.25s | 12.23s |
|
|
259
|
+
| 300 (900) | 715ms | **523ms** | 1.17s | 8.62s | 6.44s | 38.68s |
|
|
260
|
+
|
|
261
|
+
**Daemon on vs off** (200 projects × 3 tasks, 600 nodes):
|
|
262
|
+
|
|
263
|
+
| mode | omni warm | turbo warm | nx warm | omni cold | turbo cold | nx cold |
|
|
264
|
+
| --- | --- | --- | --- | --- | --- | --- |
|
|
265
|
+
| daemon on | 454ms | **361ms** | 915ms | 5.60s | 4.31s | 19.50s |
|
|
266
|
+
| daemon off | 455ms | **359ms** | 924ms | 5.62s | 4.32s | 15.27s |
|
|
267
|
+
|
|
268
|
+
**Observations**
|
|
269
|
+
|
|
270
|
+
- **Warm overhead:** omni and turbo are close (turbo pulls slightly ahead as
|
|
271
|
+
scale grows); nx is consistently **~2.3–4.7× slower** on warm cache hits. At
|
|
272
|
+
small scale (50 projects) omni is fastest; from ~120 projects up turbo leads.
|
|
273
|
+
- **Graph shape matters most for cold:** the `chain` strategy (deep, low
|
|
274
|
+
parallelism) roughly doubles cold time for omni/turbo and gives nx its worst
|
|
275
|
+
warm number, while `isolated`/`layered` (wide, parallel) are cheapest.
|
|
276
|
+
- **Scale:** warm overhead grows roughly linearly with task-graph size for all
|
|
277
|
+
three; nx **cold** scales worst (38.7s at 300 projects vs 6–9s for the
|
|
278
|
+
others).
|
|
279
|
+
- **Daemons:** on/off barely moves omni/turbo (omni has none; turbo warm is
|
|
280
|
+
unchanged) and nx warm is essentially flat — but nx **cold is faster with the
|
|
281
|
+
daemon off** (~15s vs ~19s) because daemon-mode cold pays a teardown/restart
|
|
282
|
+
each run. So nx's daemon does not materially reduce the per-invocation warm
|
|
283
|
+
overhead this benchmark isolates.
|
|
284
|
+
|
|
285
|
+
> Reproduce with the script above; exact numbers vary by machine, the relative
|
|
286
|
+
> ratios are the takeaway.
|
|
287
|
+
|
|
288
|
+
## Tool adapters
|
|
289
|
+
|
|
290
|
+
Each runner is a self-contained adapter (`src/tools/<tool>.ts`) that owns
|
|
291
|
+
*everything* tool-specific, so the generator and the other tools stay
|
|
292
|
+
decoupled. An adapter declares:
|
|
293
|
+
|
|
294
|
+
- `supportedVersions` — semver ranges it supports. The version to install is
|
|
295
|
+
configurable (`versions.<tool>` / `--<tool>-version`); if it falls outside
|
|
296
|
+
the supported ranges the harness fails fast with a clear error. External
|
|
297
|
+
tools (omni) instead implement `detectVersion()` and validate the installed
|
|
298
|
+
binary.
|
|
299
|
+
- `devDependencies(config)` — the npm packages it needs in the root
|
|
300
|
+
`package.json`.
|
|
301
|
+
- `setup(ctx)` — derives and writes its own config from the generated
|
|
302
|
+
`projects` (e.g. `turbo.json`, `nx.json` + `project.json`, `.moon/*.yml` +
|
|
303
|
+
`moon.yml`, `workspace.omni.yaml` + `project.omni.yaml`).
|
|
304
|
+
- `run` / `env` / `clearCaches` / `stopDaemon` — the runtime behavior.
|
|
305
|
+
|
|
306
|
+
The generator only writes the neutral workspace (projects, `src/index.js`,
|
|
307
|
+
`task.mjs`), then hands the project list to each enabled adapter. Adding a new
|
|
308
|
+
runner is a single new file plus registering it in `src/tools/index.ts`.
|
|
309
|
+
|
|
310
|
+
## Notes
|
|
311
|
+
|
|
312
|
+
- The dependency graph is deterministic for a given `seed`.
|
|
313
|
+
- Generated workspaces are self-contained and safe to place anywhere outside
|
|
314
|
+
this repository (each has its own `workspace.omni.yaml`).
|
|
315
|
+
|
|
316
|
+
### Known limitations
|
|
317
|
+
|
|
318
|
+
- Numbers are wall-clock process timings on a single machine; absolute values
|
|
319
|
+
vary by hardware, but the harness isolates *relative* discovery/caching
|
|
320
|
+
overhead.
|
|
321
|
+
- Cold runs are fully fresh per tool (caches cleared; daemons torn down in
|
|
322
|
+
daemon mode), so cold includes each tool's start-up cost. Warm runs are the
|
|
323
|
+
primary overhead metric.
|
|
324
|
+
- Task output is captured (piped) for all runners equally so every tool's
|
|
325
|
+
log-capture path is exercised.
|
|
326
|
+
- moon only enables its cache inside a git repository, so generated workspaces
|
|
327
|
+
are committed automatically; benchmarking an existing workspace assumes it is
|
|
328
|
+
already a git repo.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Tool } from '../config';
|
|
2
|
+
import { Stats } from './stats';
|
|
3
|
+
export interface RunSample {
|
|
4
|
+
durationMs: number;
|
|
5
|
+
exitCode: number;
|
|
6
|
+
stdout: string;
|
|
7
|
+
stderr: string;
|
|
8
|
+
/** Number of tasks that actually executed (0 == a full cache hit). */
|
|
9
|
+
executed: number;
|
|
10
|
+
ok: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface ScenarioResult {
|
|
13
|
+
runs: number;
|
|
14
|
+
failures: number;
|
|
15
|
+
stats: Stats;
|
|
16
|
+
/** Median number of tasks that actually executed across the runs. */
|
|
17
|
+
executedMedian: number;
|
|
18
|
+
}
|
|
19
|
+
export interface ToolResult {
|
|
20
|
+
tool: Tool;
|
|
21
|
+
task: string;
|
|
22
|
+
/** Size of the executed task graph (tasks run on a cold, uncached run). */
|
|
23
|
+
taskGraphSize: number;
|
|
24
|
+
cold: ScenarioResult;
|
|
25
|
+
warm: ScenarioResult;
|
|
26
|
+
error?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface BenchmarkResult {
|
|
29
|
+
rootDir: string;
|
|
30
|
+
task: string;
|
|
31
|
+
projects: number;
|
|
32
|
+
tasksPerProject: number;
|
|
33
|
+
concurrency: number;
|
|
34
|
+
daemon: boolean;
|
|
35
|
+
/** Resolved version of each benchmarked tool (detected for omni). */
|
|
36
|
+
versions: Record<string, string | null>;
|
|
37
|
+
generatedAt: string;
|
|
38
|
+
tools: ToolResult[];
|
|
39
|
+
}
|
|
40
|
+
export type BenchEvent = {
|
|
41
|
+
kind: "tool-start";
|
|
42
|
+
tool: Tool;
|
|
43
|
+
} | {
|
|
44
|
+
kind: "scenario";
|
|
45
|
+
tool: Tool;
|
|
46
|
+
scenario: "cold" | "warm";
|
|
47
|
+
run: number;
|
|
48
|
+
total: number;
|
|
49
|
+
sample: RunSample;
|
|
50
|
+
} | {
|
|
51
|
+
kind: "tool-error";
|
|
52
|
+
tool: Tool;
|
|
53
|
+
error: string;
|
|
54
|
+
} | {
|
|
55
|
+
kind: "tool-unsuccessful";
|
|
56
|
+
tool: Tool;
|
|
57
|
+
sample: RunSample;
|
|
58
|
+
};
|
|
59
|
+
export interface RunBenchmarkOptions {
|
|
60
|
+
tools?: Tool[] | undefined;
|
|
61
|
+
task?: string | undefined;
|
|
62
|
+
coldRuns?: number | undefined;
|
|
63
|
+
warmRuns?: number | undefined;
|
|
64
|
+
concurrency?: number | undefined;
|
|
65
|
+
/** Allow each tool's persistent daemon (default true). */
|
|
66
|
+
daemon?: boolean | undefined;
|
|
67
|
+
onEvent?: ((event: BenchEvent) => void) | undefined;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Benchmark the enabled tools against an already-generated workspace.
|
|
71
|
+
*
|
|
72
|
+
* For each tool we measure two scenarios:
|
|
73
|
+
* - cold: caches + outputs wiped before every run (discovery + full exec + cache write)
|
|
74
|
+
* - warm: caches primed, so ideally every task is a cache hit
|
|
75
|
+
* (isolates discovery + cache-restore overhead)
|
|
76
|
+
*
|
|
77
|
+
* A tool-agnostic execution counter (see the generated task runner) records how
|
|
78
|
+
* many tasks actually ran, so warm-run cache effectiveness is *verified* rather
|
|
79
|
+
* than assumed. Concurrency is pinned identically across all runners.
|
|
80
|
+
*/
|
|
81
|
+
export declare function runBenchmark(rootDir: string, options?: RunBenchmarkOptions): Promise<BenchmarkResult>;
|
|
82
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bench/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAuB,KAAK,IAAI,EAAE,MAAM,WAAW,CAAC;AAG3D,OAAO,EAAgB,KAAK,KAAK,EAAE,MAAM,SAAS,CAAC;AAEnD,MAAM,WAAW,SAAS;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;IACb,qEAAqE;IACrE,cAAc,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,cAAc,CAAC;IACrB,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,qEAAqE;IACrE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,UAAU,EAAE,CAAC;CACvB;AAED,MAAM,MAAM,UAAU,GAChB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAClC;IACI,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,SAAS,CAAC;CACrB,GACD;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjD;IACI,IAAI,EAAE,mBAAmB,CAAC;IAC1B,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,SAAS,CAAC;CACrB,CAAC;AAER,MAAM,WAAW,mBAAmB;IAChC,KAAK,CAAC,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,0DAA0D;IAC1D,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CACvD;AAuED;;;;;;;;;;;GAWG;AACH,wBAAsB,YAAY,CAC9B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,mBAAwB,GAClC,OAAO,CAAC,eAAe,CAAC,CA8J1B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/bench/install.ts"],"names":[],"mappings":"AAEA,8DAA8D;AAC9D,wBAAsB,gBAAgB,CAClC,GAAG,EAAE,MAAM,EACX,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAC/B,OAAO,CAAC,IAAI,CAAC,CAKf"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BenchmarkResult } from './index';
|
|
2
|
+
/**
|
|
3
|
+
* Render a human-readable comparison table plus a short takeaway. The warm
|
|
4
|
+
* column is the key metric: with all tasks cached it approximates each tool's
|
|
5
|
+
* discovery + cache-restore overhead. The warm-cache-hit column verifies that
|
|
6
|
+
* assumption held (should be 100%).
|
|
7
|
+
*/
|
|
8
|
+
export declare function formatReport(result: BenchmarkResult): string;
|
|
9
|
+
//# sourceMappingURL=report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/bench/report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAc,MAAM,SAAS,CAAC;AA6B3D;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAkG5D"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Summary statistics for a set of timing samples (all in milliseconds). */
|
|
2
|
+
export interface Stats {
|
|
3
|
+
samples: number[];
|
|
4
|
+
min: number;
|
|
5
|
+
max: number;
|
|
6
|
+
mean: number;
|
|
7
|
+
median: number;
|
|
8
|
+
stddev: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function computeStats(samples: number[]): Stats;
|
|
11
|
+
export declare function formatMs(ms: number): string;
|
|
12
|
+
//# sourceMappingURL=stats.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../src/bench/stats.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,MAAM,WAAW,KAAK;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,KAAK,CAsBrD;AAED,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAG3C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* The supported inter-project dependency graph shapes. These control how much
|
|
4
|
+
* of a task graph a runner has to walk during discovery / scheduling, which is
|
|
5
|
+
* what we are trying to measure.
|
|
6
|
+
*/
|
|
7
|
+
export declare const DEPENDENCY_STRATEGIES: readonly ["isolated", "chain", "fan-out", "layered", "random"];
|
|
8
|
+
export declare const DependencyStrategySchema: z.ZodEnum<{
|
|
9
|
+
isolated: "isolated";
|
|
10
|
+
chain: "chain";
|
|
11
|
+
"fan-out": "fan-out";
|
|
12
|
+
layered: "layered";
|
|
13
|
+
random: "random";
|
|
14
|
+
}>;
|
|
15
|
+
export type DependencyStrategy = z.infer<typeof DependencyStrategySchema>;
|
|
16
|
+
/** The task runners we know how to generate configuration for and benchmark. */
|
|
17
|
+
export declare const TOOLS: readonly ["omni", "turbo", "nx", "moon"];
|
|
18
|
+
export declare const ToolSchema: z.ZodEnum<{
|
|
19
|
+
omni: "omni";
|
|
20
|
+
turbo: "turbo";
|
|
21
|
+
nx: "nx";
|
|
22
|
+
moon: "moon";
|
|
23
|
+
}>;
|
|
24
|
+
export type Tool = z.infer<typeof ToolSchema>;
|
|
25
|
+
export declare const DependencyConfigSchema: z.ZodPrefault<z.ZodObject<{
|
|
26
|
+
strategy: z.ZodDefault<z.ZodEnum<{
|
|
27
|
+
isolated: "isolated";
|
|
28
|
+
chain: "chain";
|
|
29
|
+
"fan-out": "fan-out";
|
|
30
|
+
layered: "layered";
|
|
31
|
+
random: "random";
|
|
32
|
+
}>>;
|
|
33
|
+
layers: z.ZodDefault<z.ZodNumber>;
|
|
34
|
+
fanout: z.ZodDefault<z.ZodNumber>;
|
|
35
|
+
edgeProbability: z.ZodDefault<z.ZodNumber>;
|
|
36
|
+
}, z.core.$strip>>;
|
|
37
|
+
export declare const TaskConfigSchema: z.ZodPrefault<z.ZodObject<{
|
|
38
|
+
logLines: z.ZodDefault<z.ZodNumber>;
|
|
39
|
+
workIterations: z.ZodDefault<z.ZodNumber>;
|
|
40
|
+
outputFiles: z.ZodDefault<z.ZodNumber>;
|
|
41
|
+
chainWithinProject: z.ZodDefault<z.ZodBoolean>;
|
|
42
|
+
fanUpstream: z.ZodDefault<z.ZodBoolean>;
|
|
43
|
+
}, z.core.$strip>>;
|
|
44
|
+
export declare const VersionsConfigSchema: z.ZodPrefault<z.ZodObject<{
|
|
45
|
+
turbo: z.ZodDefault<z.ZodString>;
|
|
46
|
+
nx: z.ZodDefault<z.ZodString>;
|
|
47
|
+
moon: z.ZodDefault<z.ZodString>;
|
|
48
|
+
bun: z.ZodDefault<z.ZodString>;
|
|
49
|
+
}, z.core.$strip>>;
|
|
50
|
+
export declare const HarnessConfigSchema: z.ZodObject<{
|
|
51
|
+
seed: z.ZodDefault<z.ZodNumber>;
|
|
52
|
+
projectPrefix: z.ZodDefault<z.ZodString>;
|
|
53
|
+
projects: z.ZodDefault<z.ZodNumber>;
|
|
54
|
+
tasksPerProject: z.ZodDefault<z.ZodNumber>;
|
|
55
|
+
dependency: z.ZodPrefault<z.ZodObject<{
|
|
56
|
+
strategy: z.ZodDefault<z.ZodEnum<{
|
|
57
|
+
isolated: "isolated";
|
|
58
|
+
chain: "chain";
|
|
59
|
+
"fan-out": "fan-out";
|
|
60
|
+
layered: "layered";
|
|
61
|
+
random: "random";
|
|
62
|
+
}>>;
|
|
63
|
+
layers: z.ZodDefault<z.ZodNumber>;
|
|
64
|
+
fanout: z.ZodDefault<z.ZodNumber>;
|
|
65
|
+
edgeProbability: z.ZodDefault<z.ZodNumber>;
|
|
66
|
+
}, z.core.$strip>>;
|
|
67
|
+
task: z.ZodPrefault<z.ZodObject<{
|
|
68
|
+
logLines: z.ZodDefault<z.ZodNumber>;
|
|
69
|
+
workIterations: z.ZodDefault<z.ZodNumber>;
|
|
70
|
+
outputFiles: z.ZodDefault<z.ZodNumber>;
|
|
71
|
+
chainWithinProject: z.ZodDefault<z.ZodBoolean>;
|
|
72
|
+
fanUpstream: z.ZodDefault<z.ZodBoolean>;
|
|
73
|
+
}, z.core.$strip>>;
|
|
74
|
+
tools: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
75
|
+
omni: "omni";
|
|
76
|
+
turbo: "turbo";
|
|
77
|
+
nx: "nx";
|
|
78
|
+
moon: "moon";
|
|
79
|
+
}>>>;
|
|
80
|
+
versions: z.ZodPrefault<z.ZodObject<{
|
|
81
|
+
turbo: z.ZodDefault<z.ZodString>;
|
|
82
|
+
nx: z.ZodDefault<z.ZodString>;
|
|
83
|
+
moon: z.ZodDefault<z.ZodString>;
|
|
84
|
+
bun: z.ZodDefault<z.ZodString>;
|
|
85
|
+
}, z.core.$strip>>;
|
|
86
|
+
}, z.core.$strip>;
|
|
87
|
+
export type HarnessConfig = z.infer<typeof HarnessConfigSchema>;
|
|
88
|
+
export type HarnessConfigInput = z.input<typeof HarnessConfigSchema>;
|
|
89
|
+
/** Parse and fill defaults for a (possibly partial) harness config. */
|
|
90
|
+
export declare function resolveConfig(input?: HarnessConfigInput): HarnessConfig;
|
|
91
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,gEAMxB,CAAC;AAEX,eAAO,MAAM,wBAAwB;;;;;;EAAgC,CAAC;AACtE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,gFAAgF;AAChF,eAAO,MAAM,KAAK,0CAA2C,CAAC;AAC9D,eAAO,MAAM,UAAU;;;;;EAAgB,CAAC;AACxC,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAE9C,eAAO,MAAM,sBAAsB;;;;;;;;;;;kBA0BlB,CAAC;AAElB,eAAO,MAAM,gBAAgB;;;;;;kBAmCZ,CAAC;AAElB,eAAO,MAAM,oBAAoB;;;;;kBAOhB,CAAC;AAElB,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgC9B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAChE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAErE,uEAAuE;AACvE,wBAAgB,aAAa,CAAC,KAAK,CAAC,EAAE,kBAAkB,GAAG,aAAa,CAEvE"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { HarnessConfig, HarnessConfigInput } from '../config';
|
|
2
|
+
import { ProjectNode } from '../graph';
|
|
3
|
+
export interface GenerateResult {
|
|
4
|
+
rootDir: string;
|
|
5
|
+
config: HarnessConfig;
|
|
6
|
+
projects: ProjectNode[];
|
|
7
|
+
/** Every file written, workspace-relative. */
|
|
8
|
+
files: string[];
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Generate a complete benchmark workspace at `rootDir`. Existing contents at
|
|
12
|
+
* `rootDir` are removed first so the workspace is reproducible.
|
|
13
|
+
*
|
|
14
|
+
* The generator only produces the neutral, tool-agnostic workspace (projects,
|
|
15
|
+
* sources, task runners). Each enabled tool then writes its own configuration
|
|
16
|
+
* via its adapter, keeping the tools fully decoupled.
|
|
17
|
+
*/
|
|
18
|
+
export declare function generateWorkspace(rootDir: string, input?: HarnessConfigInput): Promise<GenerateResult>;
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/generate/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACH,KAAK,aAAa,EAClB,KAAK,kBAAkB,EAE1B,MAAM,WAAW,CAAC;AACnB,OAAO,EAAc,KAAK,WAAW,EAAa,MAAM,UAAU,CAAC;AAInE,MAAM,WAAW,cAAc;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,8CAA8C;IAC9C,KAAK,EAAE,MAAM,EAAE,CAAC;CACnB;AAsHD;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACnC,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,cAAc,CAAC,CAmEzB"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { HarnessConfig } from '../config';
|
|
2
|
+
import { ProjectNode } from '../graph';
|
|
3
|
+
/**
|
|
4
|
+
* The minimal source file each project ships. It exists so that every runner
|
|
5
|
+
* has a real input file to hash for cache keys.
|
|
6
|
+
*/
|
|
7
|
+
export declare function sourceFile(project: ProjectNode): string;
|
|
8
|
+
/**
|
|
9
|
+
* The task runner every project uses. It is intentionally tiny but does real
|
|
10
|
+
* work that exercises each runner's caching + log-capture machinery:
|
|
11
|
+
* - reads its own source (a cache input),
|
|
12
|
+
* - performs a deterministic CPU loop,
|
|
13
|
+
* - prints a configurable number of log lines to stdout,
|
|
14
|
+
* - writes deterministic output file(s) into dist/ (cache outputs).
|
|
15
|
+
*
|
|
16
|
+
* Determinism matters: identical inputs => identical outputs => cache hits on
|
|
17
|
+
* warm runs, which is exactly what we want to measure.
|
|
18
|
+
*/
|
|
19
|
+
export declare function taskRunner(config: HarnessConfig, project: ProjectNode): string;
|
|
20
|
+
//# sourceMappingURL=templates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/generate/templates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CASvD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CACtB,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,WAAW,GACrB,MAAM,CAsDR"}
|
package/dist/graph.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { HarnessConfig } from './config';
|
|
2
|
+
/** A single generated project and the upstream projects it depends on. */
|
|
3
|
+
export interface ProjectNode {
|
|
4
|
+
/** Zero-based index in the generated set. */
|
|
5
|
+
index: number;
|
|
6
|
+
/** Package name, e.g. `bench-p0007`. */
|
|
7
|
+
name: string;
|
|
8
|
+
/** Workspace-relative POSIX directory, e.g. `packages/bench-p0007`. */
|
|
9
|
+
dir: string;
|
|
10
|
+
/** Indices of upstream projects this project depends on. */
|
|
11
|
+
dependencies: number[];
|
|
12
|
+
}
|
|
13
|
+
export declare function projectName(config: HarnessConfig, index: number): string;
|
|
14
|
+
/**
|
|
15
|
+
* Build the full project graph for a config. Dependencies always point to
|
|
16
|
+
* lower indices, guaranteeing an acyclic graph.
|
|
17
|
+
*/
|
|
18
|
+
export declare function buildGraph(config: HarnessConfig): ProjectNode[];
|
|
19
|
+
/** The task names generated for every project: `t0`, `t1`, ... */
|
|
20
|
+
export declare function taskNames(config: HarnessConfig): string[];
|
|
21
|
+
//# sourceMappingURL=graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,0EAA0E;AAC1E,MAAM,WAAW,WAAW;IACxB,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,GAAG,EAAE,MAAM,CAAC;IACZ,4DAA4D;IAC5D,YAAY,EAAE,MAAM,EAAE,CAAC;CAC1B;AAmBD,wBAAgB,WAAW,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAGxE;AA+DD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,aAAa,GAAG,WAAW,EAAE,CAa/D;AAED,kEAAkE;AAClE,wBAAgB,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,EAAE,CAEzD"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export * from './bench';
|
|
2
|
+
export { installWorkspace } from './bench/install';
|
|
3
|
+
export { formatReport } from './bench/report';
|
|
4
|
+
export type { Stats } from './bench/stats';
|
|
5
|
+
export { computeStats, formatMs } from './bench/stats';
|
|
6
|
+
export * from './config';
|
|
7
|
+
export type { GenerateResult } from './generate';
|
|
8
|
+
export { generateWorkspace } from './generate';
|
|
9
|
+
export * from './graph';
|
|
10
|
+
export type { RunSuiteOptions, SuiteEvent, SuiteResult, SuiteScenarioResult, } from './suite';
|
|
11
|
+
export { runSuite } from './suite';
|
|
12
|
+
export * from './suite/preset';
|
|
13
|
+
export { formatSuiteMarkdown } from './suite/report';
|
|
14
|
+
export type { GenerationContext, RunInvocation, ToolAdapter, ToolContext, WorkspaceWriter, } from './tools';
|
|
15
|
+
export { assertSupportedVersion, getAdapter, getAdapters, resolveToolVersions, } from './tools';
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACvD,cAAc,UAAU,CAAC;AACzB,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,cAAc,SAAS,CAAC;AACxB,YAAY,EACR,eAAe,EACf,UAAU,EACV,WAAW,EACX,mBAAmB,GACtB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,YAAY,EACR,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,WAAW,EACX,eAAe,GAClB,MAAM,SAAS,CAAC;AACjB,OAAO,EACH,sBAAsB,EACtB,UAAU,EACV,WAAW,EACX,mBAAmB,GACtB,MAAM,SAAS,CAAC"}
|