tonnage 0.1.2 → 0.2.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.
- package/AGENTS.md +2 -0
- package/CHANGELOG.md +12 -0
- package/README.md +109 -0
- package/README.mdx +143 -0
- package/dist/cli.mjs +25 -7
- package/dist/cli.mjs.map +1 -1
- package/dist/galley.d.mts +12 -0
- package/dist/galley.d.mts.map +1 -0
- package/dist/galley.mjs +12 -0
- package/dist/galley.mjs.map +1 -0
- package/dist/index.d.mts +11 -56
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -1
- package/dist/index.mjs.map +1 -1
- package/dist/{run-CZ_FO4C7.mjs → report-B3HrJ4UQ.mjs} +85 -112
- package/dist/report-B3HrJ4UQ.mjs.map +1 -0
- package/dist/run-BJN1MXRf.mjs +44 -0
- package/dist/run-BJN1MXRf.mjs.map +1 -0
- package/dist/types-Ddtp95Z3.d.mts +49 -0
- package/dist/types-Ddtp95Z3.d.mts.map +1 -0
- package/package.json +33 -27
- package/src/cli.ts +15 -2
- package/src/command-line.ts +24 -6
- package/src/galley.ts +25 -0
- package/src/report-content.ts +122 -0
- package/src/report.ts +11 -111
- package/src/run.ts +1 -1
- package/dist/run-CZ_FO4C7.mjs.map +0 -1
package/AGENTS.md
CHANGED
|
@@ -8,3 +8,5 @@ CI-first runtime JavaScript bundle measurement with checked-in README reports.
|
|
|
8
8
|
- Peer dependencies stay external by default. Use explicit `external` entries only for additional dependencies intentionally supplied by consumers.
|
|
9
9
|
- Run `tonnage write` to update a generated README section and `tonnage check` in CI to detect drift.
|
|
10
10
|
- Keep marker names stable and use the `tonnage:<name>:start` and `tonnage:<name>:end` comment forms.
|
|
11
|
+
- For a galley.md document, import `Tonnage` from `tonnage/galley`. Its config paths default to the containing document's directory. The component measures and renders a report without writing a README or requiring section markers.
|
|
12
|
+
- Await `renderTonnageMarkdown(report, config)` when using the programmatic API. CLI reports and document components share Galley's table rendering, escaping literal text and aligning byte columns to the right.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# tonnage
|
|
2
2
|
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 0521e43: Render reports through galley.md 0.1.1 native table elements and expose a Tonnage component from tonnage/galley for MDX documents. Galley is now a runtime dependency, renderTonnageMarkdown returns a Promise and must be awaited, and inline code and table text use Galley's Markdown escaping and column alignment.
|
|
8
|
+
|
|
9
|
+
## 0.1.3
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 9866ade: Upgrade comline, pass full runtime argv, add command and config-path completion with shell installation commands, and report ignored-option warnings on stderr while preserving asynchronous config loading.
|
|
14
|
+
|
|
3
15
|
## 0.1.2
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -15,11 +15,43 @@ per bundle.
|
|
|
15
15
|
Add the generated-section comments to the target README, then create a config
|
|
16
16
|
beside the package manifest. The complete configuration exhibit is in
|
|
17
17
|
[examples/tonnage.config.ts](./examples/tonnage.config.ts).
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { defineConfig, type TonnageConfig } from "tonnage"
|
|
21
|
+
|
|
22
|
+
// @exhibit-region start config
|
|
23
|
+
const config: TonnageConfig = defineConfig({
|
|
24
|
+
exports: {
|
|
25
|
+
exclude: [`./package.json`],
|
|
26
|
+
},
|
|
27
|
+
marker: `my-package`,
|
|
28
|
+
recipes: [
|
|
29
|
+
{
|
|
30
|
+
entry: `examples/recipes/react-app.ts`,
|
|
31
|
+
name: `React app`,
|
|
32
|
+
platform: `browser`,
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
export default config
|
|
38
|
+
// @exhibit-region end config
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
|
|
18
42
|
Each recipe points to a reviewable entry file such as
|
|
19
43
|
[examples/recipes/react-app.ts](./examples/recipes/react-app.ts). Use named
|
|
20
44
|
imports in these files to represent the runtime surface a real application uses;
|
|
21
45
|
unused package exports are tree-shaken.
|
|
22
46
|
|
|
47
|
+
```ts
|
|
48
|
+
// @exhibit-region start recipe
|
|
49
|
+
export { atom } from "my-package"
|
|
50
|
+
export { useO } from "my-package/react"
|
|
51
|
+
// @exhibit-region end recipe
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
|
|
23
55
|
The default generated-section marker is `default`; the example uses `my-package`.
|
|
24
56
|
The opening and closing comments use the forms
|
|
25
57
|
`tonnage:my-package:start` and `tonnage:my-package:end`.
|
|
@@ -31,12 +63,43 @@ Run `tonnage write` during development to update the README. Run
|
|
|
31
63
|
nonzero when the README is stale. Run `tonnage --help` to see both commands and
|
|
32
64
|
their optional config-path arguments.
|
|
33
65
|
|
|
66
|
+
Pass a config path with `tonnage check path/to/tonnage.config.ts` or
|
|
67
|
+
`tonnage write path/to/tonnage.config.ts`. Otherwise, Tonnage looks in the current
|
|
68
|
+
directory for `tonnage.config.ts`, then `tonnage.config.mjs`, then
|
|
69
|
+
`tonnage.config.js`. Config modules may use top-level `await`. Missing configs
|
|
70
|
+
are errors. Use `--` before a config path that starts with a dash.
|
|
71
|
+
|
|
72
|
+
Unknown options are ignored with warnings on stderr. Warnings do not change the
|
|
73
|
+
exit status; `check` still exits nonzero when the report is stale.
|
|
74
|
+
|
|
34
75
|
By default the tool reads `package.json`, writes `README.md`, and measures every
|
|
35
76
|
public export except `./package.json`. Paths are resolved relative to the config
|
|
36
77
|
file. Use `exports.include` or `exports.exclude` to select subpaths, recipe entry
|
|
37
78
|
files to describe realistic runtime boundaries, and `external` for non-peer
|
|
38
79
|
imports that the package intentionally leaves to its consumers.
|
|
39
80
|
|
|
81
|
+
### Shell completion
|
|
82
|
+
|
|
83
|
+
With `tonnage` available on your shell's `PATH`, install completion for your shell:
|
|
84
|
+
|
|
85
|
+
```sh
|
|
86
|
+
tonnage completion install bash
|
|
87
|
+
tonnage completion install zsh
|
|
88
|
+
tonnage completion install fish
|
|
89
|
+
tonnage completion install nushell
|
|
90
|
+
tonnage completion install carapace
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Choose the integration you use. Completion suggests commands, help options, and
|
|
94
|
+
config paths without loading your config or measuring bundles. Installation
|
|
95
|
+
checks the shell's prerequisites and writes to its completion directory without
|
|
96
|
+
editing shell profiles. It reports any setup needed for your shell. If Nushell
|
|
97
|
+
already uses Carapace, install only the Carapace integration.
|
|
98
|
+
|
|
99
|
+
Run `tonnage completion bash` (or another target above) to print the integration
|
|
100
|
+
file without installing it. The `completion` command and comline's internal
|
|
101
|
+
completion protocol commands are reserved for shell integration.
|
|
102
|
+
|
|
40
103
|
## Report layout
|
|
41
104
|
|
|
42
105
|
Generated reports adapt to the measurements they contain. An exports-only or
|
|
@@ -50,6 +113,23 @@ JavaScript bytes, with declarations, source maps, CSS, and other assets excluded
|
|
|
50
113
|
Peer dependencies remain external, and shared modules are counted once in each
|
|
51
114
|
bundle.
|
|
52
115
|
|
|
116
|
+
Reports use Galley's native table elements, with right-aligned byte columns and
|
|
117
|
+
literal escaping for import names, entry paths, and recipe labels.
|
|
118
|
+
|
|
119
|
+
For programmatic use, await both measurement and Markdown rendering:
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
import {
|
|
123
|
+
createTonnageReport,
|
|
124
|
+
defineConfig,
|
|
125
|
+
renderTonnageMarkdown,
|
|
126
|
+
} from "tonnage"
|
|
127
|
+
|
|
128
|
+
const config = defineConfig({ platform: "node" })
|
|
129
|
+
const report = await createTonnageReport(config, process.cwd())
|
|
130
|
+
const markdown = await renderTonnageMarkdown(report, config)
|
|
131
|
+
```
|
|
132
|
+
|
|
53
133
|
## Package resolution and platforms
|
|
54
134
|
|
|
55
135
|
Tonnage resolves the package's own public import name from the manifest selected
|
|
@@ -67,3 +147,32 @@ commonly fall through to their `default` target. Set `platform` to `browser` or
|
|
|
67
147
|
`node` when that runtime is what you want to measure; those choices retain
|
|
68
148
|
esbuild's native export conditions and main-field behavior. A recipe's
|
|
69
149
|
`platform` overrides the report-wide setting for that recipe.
|
|
150
|
+
|
|
151
|
+
## MDX documents
|
|
152
|
+
|
|
153
|
+
Use [galley.md](https://www.npmjs.com/package/galley.md) to compose a README from source examples and reports:
|
|
154
|
+
|
|
155
|
+
```mdx
|
|
156
|
+
import { Tonnage } from "tonnage/galley"
|
|
157
|
+
import config from "./tonnage.config.ts"
|
|
158
|
+
import Example from "./examples/recipes/react-app.ts" with { type: "code", lang: "ts" }
|
|
159
|
+
|
|
160
|
+
<Example />
|
|
161
|
+
|
|
162
|
+
<Tonnage config={config} />
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
The component resolves paths relative to the containing document. Pass `directory` to measure another package. It produces the same tables as the CLI without writing a README or requiring generated-section markers. Tonnage includes Galley as a runtime dependency; add `galley.md` directly to your project's development dependencies to run `galley write` and `galley check` when authoring documents.
|
|
166
|
+
|
|
167
|
+
## Bundle size
|
|
168
|
+
|
|
169
|
+
Package export sizes include complete runtime export surfaces.
|
|
170
|
+
|
|
171
|
+
Sizes are exact minified and level-9 gzip JavaScript byte counts. Declarations, source maps, CSS, and other assets are excluded. Peer dependencies stay external, and shared modules are counted once per bundle.
|
|
172
|
+
|
|
173
|
+
| Import | Minified JS | Gzip JS |
|
|
174
|
+
| ---------------- | ----------: | --------: |
|
|
175
|
+
| `tonnage` | 491,915 B | 153,965 B |
|
|
176
|
+
| `tonnage/galley` | 484,581 B | 151,561 B |
|
|
177
|
+
|
|
178
|
+
Report maintained with [tonnage](https://github.com/jeremybanka/tonnage).
|
package/README.mdx
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { Tonnage } from "tonnage/galley"
|
|
2
|
+
import Configuration from "./examples/tonnage.config.ts" with { type: "code", lang: "ts" }
|
|
3
|
+
import Recipe from "./examples/recipes/react-app.ts" with { type: "code", lang: "ts" }
|
|
4
|
+
|
|
5
|
+
# tonnage
|
|
6
|
+
|
|
7
|
+
Keep exact bundle size tables in a package README and fail CI when the checked-in
|
|
8
|
+
numbers drift.
|
|
9
|
+
|
|
10
|
+
The tool bundles real public package imports with esbuild, minifies the result,
|
|
11
|
+
and reports JavaScript bytes before and after level-9 gzip. Public-module rows
|
|
12
|
+
retain every runtime export; recipe entry files can select named exports and
|
|
13
|
+
tree-shake the rest. Declarations, source maps, CSS, and other assets are not
|
|
14
|
+
counted. Peer dependencies stay external, and shared modules are counted once
|
|
15
|
+
per bundle.
|
|
16
|
+
|
|
17
|
+
## Configure
|
|
18
|
+
|
|
19
|
+
Add the generated-section comments to the target README, then create a config
|
|
20
|
+
beside the package manifest. The complete configuration exhibit is in
|
|
21
|
+
[examples/tonnage.config.ts](./examples/tonnage.config.ts).
|
|
22
|
+
<Configuration />
|
|
23
|
+
|
|
24
|
+
Each recipe points to a reviewable entry file such as
|
|
25
|
+
[examples/recipes/react-app.ts](./examples/recipes/react-app.ts). Use named
|
|
26
|
+
imports in these files to represent the runtime surface a real application uses;
|
|
27
|
+
unused package exports are tree-shaken.
|
|
28
|
+
|
|
29
|
+
<Recipe />
|
|
30
|
+
|
|
31
|
+
The default generated-section marker is `default`; the example uses `my-package`.
|
|
32
|
+
The opening and closing comments use the forms
|
|
33
|
+
`tonnage:my-package:start` and `tonnage:my-package:end`.
|
|
34
|
+
|
|
35
|
+
## Run
|
|
36
|
+
|
|
37
|
+
Run `tonnage write` during development to update the README. Run
|
|
38
|
+
`tonnage check` in CI to recompute the same report without writing and exit
|
|
39
|
+
nonzero when the README is stale. Run `tonnage --help` to see both commands and
|
|
40
|
+
their optional config-path arguments.
|
|
41
|
+
|
|
42
|
+
Pass a config path with `tonnage check path/to/tonnage.config.ts` or
|
|
43
|
+
`tonnage write path/to/tonnage.config.ts`. Otherwise, Tonnage looks in the current
|
|
44
|
+
directory for `tonnage.config.ts`, then `tonnage.config.mjs`, then
|
|
45
|
+
`tonnage.config.js`. Config modules may use top-level `await`. Missing configs
|
|
46
|
+
are errors. Use `--` before a config path that starts with a dash.
|
|
47
|
+
|
|
48
|
+
Unknown options are ignored with warnings on stderr. Warnings do not change the
|
|
49
|
+
exit status; `check` still exits nonzero when the report is stale.
|
|
50
|
+
|
|
51
|
+
By default the tool reads `package.json`, writes `README.md`, and measures every
|
|
52
|
+
public export except `./package.json`. Paths are resolved relative to the config
|
|
53
|
+
file. Use `exports.include` or `exports.exclude` to select subpaths, recipe entry
|
|
54
|
+
files to describe realistic runtime boundaries, and `external` for non-peer
|
|
55
|
+
imports that the package intentionally leaves to its consumers.
|
|
56
|
+
|
|
57
|
+
### Shell completion
|
|
58
|
+
|
|
59
|
+
With `tonnage` available on your shell's `PATH`, install completion for your shell:
|
|
60
|
+
|
|
61
|
+
```sh
|
|
62
|
+
tonnage completion install bash
|
|
63
|
+
tonnage completion install zsh
|
|
64
|
+
tonnage completion install fish
|
|
65
|
+
tonnage completion install nushell
|
|
66
|
+
tonnage completion install carapace
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Choose the integration you use. Completion suggests commands, help options, and
|
|
70
|
+
config paths without loading your config or measuring bundles. Installation
|
|
71
|
+
checks the shell's prerequisites and writes to its completion directory without
|
|
72
|
+
editing shell profiles. It reports any setup needed for your shell. If Nushell
|
|
73
|
+
already uses Carapace, install only the Carapace integration.
|
|
74
|
+
|
|
75
|
+
Run `tonnage completion bash` (or another target above) to print the integration
|
|
76
|
+
file without installing it. The `completion` command and comline's internal
|
|
77
|
+
completion protocol commands are reserved for shell integration.
|
|
78
|
+
|
|
79
|
+
## Report layout
|
|
80
|
+
|
|
81
|
+
Generated reports adapt to the measurements they contain. An exports-only or
|
|
82
|
+
recipes-only report puts its table directly below the configured report heading
|
|
83
|
+
and describes only that type of measurement. A report with both types labels the
|
|
84
|
+
tables `Package exports` and `Usage examples` so readers can distinguish complete
|
|
85
|
+
runtime export surfaces from tree-shaken recipe bundles.
|
|
86
|
+
|
|
87
|
+
Every layout states the exact measurement semantics: minified and level-9 gzip
|
|
88
|
+
JavaScript bytes, with declarations, source maps, CSS, and other assets excluded.
|
|
89
|
+
Peer dependencies remain external, and shared modules are counted once in each
|
|
90
|
+
bundle.
|
|
91
|
+
|
|
92
|
+
Reports use Galley's native table elements, with right-aligned byte columns and
|
|
93
|
+
literal escaping for import names, entry paths, and recipe labels.
|
|
94
|
+
|
|
95
|
+
For programmatic use, await both measurement and Markdown rendering:
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
import {
|
|
99
|
+
createTonnageReport,
|
|
100
|
+
defineConfig,
|
|
101
|
+
renderTonnageMarkdown,
|
|
102
|
+
} from "tonnage"
|
|
103
|
+
|
|
104
|
+
const config = defineConfig({ platform: "node" })
|
|
105
|
+
const report = await createTonnageReport(config, process.cwd())
|
|
106
|
+
const markdown = await renderTonnageMarkdown(report, config)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Package resolution and platforms
|
|
110
|
+
|
|
111
|
+
Tonnage resolves the package's own public import name from the manifest selected
|
|
112
|
+
by `packageJson`; a workspace package does not need to install or declare itself
|
|
113
|
+
as a dependency. Root and subpath imports still go through esbuild's package
|
|
114
|
+
resolver, so the manifest's `exports` restrictions and conditions apply. Runtime
|
|
115
|
+
dependencies resolve from the measured package, while its peer dependencies stay
|
|
116
|
+
external.
|
|
117
|
+
|
|
118
|
+
The default `platform` is `neutral`. For packages without `exports`, Tonnage
|
|
119
|
+
configures neutral resolution to try the `module` field and then `main`, so
|
|
120
|
+
main-only packages and dependencies are actionable by default. With conditional
|
|
121
|
+
`exports`, neutral does not enable the `browser` or `node` condition, so exports
|
|
122
|
+
commonly fall through to their `default` target. Set `platform` to `browser` or
|
|
123
|
+
`node` when that runtime is what you want to measure; those choices retain
|
|
124
|
+
esbuild's native export conditions and main-field behavior. A recipe's
|
|
125
|
+
`platform` overrides the report-wide setting for that recipe.
|
|
126
|
+
|
|
127
|
+
## MDX documents
|
|
128
|
+
|
|
129
|
+
Use [galley.md](https://www.npmjs.com/package/galley.md) to compose a README from source examples and reports:
|
|
130
|
+
|
|
131
|
+
```mdx
|
|
132
|
+
import { Tonnage } from "tonnage/galley"
|
|
133
|
+
import config from "./tonnage.config.ts"
|
|
134
|
+
import Example from "./examples/recipes/react-app.ts" with { type: "code", lang: "ts" }
|
|
135
|
+
|
|
136
|
+
<Example />
|
|
137
|
+
|
|
138
|
+
<Tonnage config={config} />
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
The component resolves paths relative to the containing document. Pass `directory` to measure another package. It produces the same tables as the CLI without writing a README or requiring generated-section markers. Tonnage includes Galley as a runtime dependency; add `galley.md` directly to your project's development dependencies to run `galley write` and `galley check` when authoring documents.
|
|
142
|
+
|
|
143
|
+
<Tonnage config={{ platform: "node", exports: { include: [".", "./galley"] } }} />
|
package/dist/cli.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { t as runTonnage } from "./run-
|
|
2
|
+
import { t as runTonnage } from "./run-BJN1MXRf.mjs";
|
|
3
3
|
import fs from "node:fs/promises";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { pathToFileURL } from "node:url";
|
|
6
|
-
import { cli, help, helpOption, optional } from "comline";
|
|
6
|
+
import { cli, completionResponse, help, helpOption, logWarnings, optional } from "comline";
|
|
7
7
|
//#region src/command-line.ts
|
|
8
8
|
const ROOT_MANUAL = helpOption(`Show help for the tonnage command line.`);
|
|
9
9
|
const WRITE_MANUAL = helpOption(`Update the configured README report.`);
|
|
@@ -22,20 +22,32 @@ const tonnageCli = cli({
|
|
|
22
22
|
write: WRITE_MANUAL,
|
|
23
23
|
"write/$configPath": WRITE_MANUAL
|
|
24
24
|
},
|
|
25
|
+
positionalCompletions: {
|
|
26
|
+
"check/$configPath": { fileSystem: `files` },
|
|
27
|
+
"write/$configPath": { fileSystem: `files` }
|
|
28
|
+
},
|
|
25
29
|
discoverConfigPath: () => void 0
|
|
26
30
|
});
|
|
31
|
+
function completeTonnageCli(args) {
|
|
32
|
+
return completionResponse(tonnageCli.definition, args);
|
|
33
|
+
}
|
|
27
34
|
function parseTonnageCli(args) {
|
|
28
|
-
const { inputs } = tonnageCli(args);
|
|
29
|
-
if (inputs.case === `` || inputs.opts.help) return {
|
|
35
|
+
const { inputs, warnings } = tonnageCli(args);
|
|
36
|
+
if (inputs.case === `` || inputs.opts.help) return {
|
|
37
|
+
kind: `help`,
|
|
38
|
+
warnings
|
|
39
|
+
};
|
|
30
40
|
const mode = inputs.case === `write` || inputs.case === `write/$configPath` ? `write` : `check`;
|
|
31
41
|
const configArgument = inputs.path[1];
|
|
32
42
|
return configArgument === void 0 ? {
|
|
33
43
|
kind: `run`,
|
|
34
|
-
mode
|
|
44
|
+
mode,
|
|
45
|
+
warnings
|
|
35
46
|
} : {
|
|
36
47
|
configArgument,
|
|
37
48
|
kind: `run`,
|
|
38
|
-
mode
|
|
49
|
+
mode,
|
|
50
|
+
warnings
|
|
39
51
|
};
|
|
40
52
|
}
|
|
41
53
|
function renderTonnageCliHelp() {
|
|
@@ -49,7 +61,13 @@ const DEFAULT_CONFIG_FILES = [
|
|
|
49
61
|
`tonnage.config.js`
|
|
50
62
|
];
|
|
51
63
|
async function main() {
|
|
52
|
-
const
|
|
64
|
+
const completion = await completeTonnageCli(process.argv);
|
|
65
|
+
if (completion !== void 0) {
|
|
66
|
+
process.stdout.write(completion);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const invocation = parseTonnageCli(process.argv);
|
|
70
|
+
logWarnings(invocation.warnings);
|
|
53
71
|
if (invocation.kind === `help`) {
|
|
54
72
|
process.stdout.write(renderTonnageCliHelp());
|
|
55
73
|
return;
|
package/dist/cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.mjs","names":[],"sources":["../src/command-line.ts","../src/cli.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"cli.mjs","names":[],"sources":["../src/command-line.ts","../src/cli.ts"],"sourcesContent":["import {\n\ttype CliWarning,\n\tcli,\n\tcompletionResponse,\n\thelp,\n\thelpOption,\n\toptional,\n} from \"comline\"\n\nimport type { TonnageMode } from \"./types.ts\"\n\nconst ROOT_MANUAL = helpOption(`Show help for the tonnage command line.`)\nconst WRITE_MANUAL = helpOption(`Update the configured README report.`)\nconst CHECK_MANUAL = helpOption(\n\t`Check that the configured README report is up to date.`,\n)\n\nconst tonnageCli = cli({\n\tcliName: `tonnage`,\n\tcliDescription: `Keep deterministic bundle size reports in README files and CI.`,\n\troutes: optional({\n\t\tcheck: optional({ $configPath: null }),\n\t\twrite: optional({ $configPath: null }),\n\t}),\n\trouteOptions: {\n\t\t\"\": ROOT_MANUAL,\n\t\tcheck: CHECK_MANUAL,\n\t\t\"check/$configPath\": CHECK_MANUAL,\n\t\twrite: WRITE_MANUAL,\n\t\t\"write/$configPath\": WRITE_MANUAL,\n\t},\n\tpositionalCompletions: {\n\t\t\"check/$configPath\": { fileSystem: `files` },\n\t\t\"write/$configPath\": { fileSystem: `files` },\n\t},\n\tdiscoverConfigPath: () => undefined,\n})\n\nexport type TonnageCliInvocation = { warnings: CliWarning[] } & (\n\t| { kind: `help` }\n\t| { configArgument?: string; kind: `run`; mode: TonnageMode }\n)\n\nexport function completeTonnageCli(\n\targs: string[],\n): Promise<string | undefined> {\n\treturn completionResponse(tonnageCli.definition, args)\n}\n\nexport function parseTonnageCli(args: string[]): TonnageCliInvocation {\n\tconst { inputs, warnings } = tonnageCli(args)\n\n\tif (inputs.case === `` || inputs.opts.help) {\n\t\treturn { kind: `help`, warnings }\n\t}\n\n\tconst mode =\n\t\tinputs.case === `write` || inputs.case === `write/$configPath`\n\t\t\t? `write`\n\t\t\t: `check`\n\tconst configArgument = inputs.path[1]\n\n\treturn configArgument === undefined\n\t\t? { kind: `run`, mode, warnings }\n\t\t: { configArgument, kind: `run`, mode, warnings }\n}\n\nexport function renderTonnageCliHelp(): string {\n\treturn help(tonnageCli.definition)\n}\n","#!/usr/bin/env node\n\nimport fs from \"node:fs/promises\"\nimport path from \"node:path\"\nimport { pathToFileURL } from \"node:url\"\n\nimport { logWarnings } from \"comline\"\n\nimport {\n\tcompleteTonnageCli,\n\tparseTonnageCli,\n\trenderTonnageCliHelp,\n} from \"./command-line.ts\"\nimport { runTonnage } from \"./run.ts\"\nimport type { TonnageConfig } from \"./types.ts\"\n\nconst DEFAULT_CONFIG_FILES = [\n\t`tonnage.config.ts`,\n\t`tonnage.config.mjs`,\n\t`tonnage.config.js`,\n]\n\nasync function main(): Promise<void> {\n\tconst completion = await completeTonnageCli(process.argv)\n\tif (completion !== undefined) {\n\t\tprocess.stdout.write(completion)\n\t\treturn\n\t}\n\n\tconst invocation = parseTonnageCli(process.argv)\n\tlogWarnings(invocation.warnings)\n\tif (invocation.kind === `help`) {\n\t\tprocess.stdout.write(renderTonnageCliHelp())\n\t\treturn\n\t}\n\n\tconst { configArgument, mode } = invocation\n\tconst configPath = await findConfig(configArgument)\n\tconst config = await loadConfig(configPath)\n\tconst result = await runTonnage(config, {\n\t\tconfigDirectory: path.dirname(configPath),\n\t\tmode,\n\t})\n\n\tif (mode === `check` && result.changed) {\n\t\tprocess.stderr.write(\n\t\t\t`${path.relative(process.cwd(), result.readmePath)} is out of date. Run tonnage write.\\n`,\n\t\t)\n\t\tprocess.exitCode = 1\n\t\treturn\n\t}\n\n\tconst readme = path.relative(process.cwd(), result.readmePath)\n\tprocess.stdout.write(\n\t\tresult.changed\n\t\t\t? `Updated ${readme}.\\n`\n\t\t\t: `${readme} is already up to date.\\n`,\n\t)\n}\n\nasync function findConfig(configArgument: string | undefined): Promise<string> {\n\tif (configArgument) {\n\t\treturn path.resolve(configArgument)\n\t}\n\n\tfor (const filename of DEFAULT_CONFIG_FILES) {\n\t\tconst candidate = path.resolve(filename)\n\t\ttry {\n\t\t\tawait fs.access(candidate)\n\t\t\treturn candidate\n\t\t} catch {\n\t\t\t// Keep looking for the next supported config filename.\n\t\t}\n\t}\n\n\tthrow new Error(\n\t\t`Could not find a tonnage config (${DEFAULT_CONFIG_FILES.join(`, `)}).`,\n\t)\n}\n\nasync function loadConfig(configPath: string): Promise<TonnageConfig> {\n\tconst imported = (await import(pathToFileURL(configPath).href)) as {\n\t\tdefault?: unknown\n\t}\n\tif (!imported.default || typeof imported.default !== `object`) {\n\t\tthrow new Error(`${configPath} must default-export a tonnage config.`)\n\t}\n\treturn imported.default\n}\n\nmain().catch((error: unknown) => {\n\tprocess.stderr.write(\n\t\t`${error instanceof Error ? error.message : String(error)}\\n`,\n\t)\n\tprocess.exitCode = 1\n})\n"],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { r as TonnageConfig } from "./types-Ddtp95Z3.mjs";
|
|
2
|
+
import { DocumentContext, Element } from "galley.md";
|
|
3
|
+
//#region src/galley.d.ts
|
|
4
|
+
export type TonnageProps = {
|
|
5
|
+
config?: TonnageConfig;
|
|
6
|
+
/** Override the document directory when measuring a different package. */
|
|
7
|
+
directory?: string;
|
|
8
|
+
};
|
|
9
|
+
/** Measure bundles and include the report in a galley.md document. */
|
|
10
|
+
export declare function Tonnage({ config, directory }: TonnageProps, context: DocumentContext): Promise<Element[]>;
|
|
11
|
+
//#endregion
|
|
12
|
+
//# sourceMappingURL=galley.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"galley.d.mts","names":[],"sources":["../src/galley.ts"],"mappings":";;;YAQY;EACX,SAAS;;EAET;;;wBAIqB,UACnB,QAAa,aAAa,cAC5B,SAAS,kBACP,QAAQ"}
|
package/dist/galley.mjs
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { r as reportContent, t as createTonnageReport } from "./report-B3HrJ4UQ.mjs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
//#region src/galley.ts
|
|
4
|
+
/** Measure bundles and include the report in a galley.md document. */
|
|
5
|
+
async function Tonnage({ config = {}, directory }, context) {
|
|
6
|
+
const report = await createTonnageReport(config, path.resolve(context.directory, directory ?? "."));
|
|
7
|
+
return reportContent(report, config);
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
export { Tonnage };
|
|
11
|
+
|
|
12
|
+
//# sourceMappingURL=galley.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"galley.mjs","names":[],"sources":["../src/galley.ts"],"sourcesContent":["import path from \"node:path\"\n\nimport type { DocumentContext, Element } from \"galley.md\"\n\nimport { createTonnageReport } from \"./report.ts\"\nimport { reportContent } from \"./report-content.ts\"\nimport type { TonnageConfig } from \"./types.ts\"\n\nexport type TonnageProps = {\n\tconfig?: TonnageConfig\n\t/** Override the document directory when measuring a different package. */\n\tdirectory?: string\n}\n\n/** Measure bundles and include the report in a galley.md document. */\nexport async function Tonnage(\n\t{ config = {}, directory }: TonnageProps,\n\tcontext: DocumentContext,\n): Promise<Element[]> {\n\tconst report = await createTonnageReport(\n\t\tconfig,\n\t\tpath.resolve(context.directory, directory ?? \".\"),\n\t)\n\treturn reportContent(report, config)\n}\n"],"mappings":";;;;AAeA,eAAsB,QACrB,EAAE,SAAS,CAAC,GAAG,aACf,SACqB;CACrB,MAAM,SAAS,MAAM,oBACpB,QACA,KAAK,QAAQ,QAAQ,WAAW,aAAa,GAAG,CACjD;CACA,OAAO,cAAc,QAAQ,MAAM;AACpC"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,53 +1,7 @@
|
|
|
1
|
+
import { a as TonnageMode, c as TonnageReport, i as TonnageExports, l as TonnageRow, n as BundlePlatform, o as TonnageRecipe, r as TonnageConfig, s as TonnageRecipeRow, t as BundleMeasurement, u as TonnageRunResult } from "./types-Ddtp95Z3.mjs";
|
|
1
2
|
import "esbuild";
|
|
2
|
-
//#region src/types.d.ts
|
|
3
|
-
type BundlePlatform = `browser` | `neutral` | `node`;
|
|
4
|
-
type TonnageExports = {
|
|
5
|
-
exclude?: readonly string[];
|
|
6
|
-
include?: readonly string[];
|
|
7
|
-
};
|
|
8
|
-
type TonnageRecipe = {
|
|
9
|
-
entry: string;
|
|
10
|
-
external?: readonly string[];
|
|
11
|
-
name: string;
|
|
12
|
-
platform?: BundlePlatform;
|
|
13
|
-
};
|
|
14
|
-
type TonnageConfig = {
|
|
15
|
-
exports?: boolean | TonnageExports;
|
|
16
|
-
external?: readonly string[];
|
|
17
|
-
heading?: string;
|
|
18
|
-
marker?: string;
|
|
19
|
-
packageJson?: string;
|
|
20
|
-
platform?: BundlePlatform;
|
|
21
|
-
readme?: string;
|
|
22
|
-
recipes?: readonly TonnageRecipe[];
|
|
23
|
-
target?: string;
|
|
24
|
-
};
|
|
25
|
-
type BundleMeasurement = {
|
|
26
|
-
gzipBytes: number;
|
|
27
|
-
rawBytes: number;
|
|
28
|
-
};
|
|
29
|
-
type TonnageRow = BundleMeasurement & {
|
|
30
|
-
imports: readonly string[];
|
|
31
|
-
name: string;
|
|
32
|
-
};
|
|
33
|
-
type TonnageRecipeRow = BundleMeasurement & {
|
|
34
|
-
entry: string;
|
|
35
|
-
name: string;
|
|
36
|
-
};
|
|
37
|
-
type TonnageReport = {
|
|
38
|
-
exports: readonly TonnageRow[];
|
|
39
|
-
packageName: string;
|
|
40
|
-
recipes: readonly TonnageRecipeRow[];
|
|
41
|
-
};
|
|
42
|
-
type TonnageMode = `check` | `write`;
|
|
43
|
-
type TonnageRunResult = {
|
|
44
|
-
changed: boolean;
|
|
45
|
-
readmePath: string;
|
|
46
|
-
report: TonnageReport;
|
|
47
|
-
};
|
|
48
|
-
//#endregion
|
|
49
3
|
//#region src/define-config.d.ts
|
|
50
|
-
declare function defineConfig(config: TonnageConfig): TonnageConfig;
|
|
4
|
+
export declare function defineConfig(config: TonnageConfig): TonnageConfig;
|
|
51
5
|
//#endregion
|
|
52
6
|
//#region src/measure.d.ts
|
|
53
7
|
type MeasureImportsOptions = {
|
|
@@ -57,25 +11,26 @@ type MeasureImportsOptions = {
|
|
|
57
11
|
target?: string | undefined;
|
|
58
12
|
};
|
|
59
13
|
type MeasureEntryOptions = MeasureImportsOptions;
|
|
60
|
-
declare function measureEntry(entry: string, options: MeasureEntryOptions): Promise<BundleMeasurement>;
|
|
61
|
-
declare function measureImports(imports: readonly string[], options: MeasureImportsOptions): Promise<BundleMeasurement>;
|
|
14
|
+
export declare function measureEntry(entry: string, options: MeasureEntryOptions): Promise<BundleMeasurement>;
|
|
15
|
+
export declare function measureImports(imports: readonly string[], options: MeasureImportsOptions): Promise<BundleMeasurement>;
|
|
62
16
|
//#endregion
|
|
63
17
|
//#region src/readme.d.ts
|
|
64
|
-
declare function tonnageMarkers(marker?: string): {
|
|
18
|
+
export declare function tonnageMarkers(marker?: string): {
|
|
65
19
|
end: string;
|
|
66
20
|
start: string;
|
|
67
21
|
};
|
|
68
|
-
declare function updateGeneratedSection(readme: string, markdown: string, marker?: string): string;
|
|
22
|
+
export declare function updateGeneratedSection(readme: string, markdown: string, marker?: string): string;
|
|
69
23
|
//#endregion
|
|
70
24
|
//#region src/report.d.ts
|
|
71
|
-
declare function createTonnageReport(config: TonnageConfig, configDirectory: string): Promise<TonnageReport>;
|
|
72
|
-
|
|
25
|
+
export declare function createTonnageReport(config: TonnageConfig, configDirectory: string): Promise<TonnageReport>;
|
|
26
|
+
/** Serialize a report with the same Galley elements used by the document component. */
|
|
27
|
+
export declare function renderTonnageMarkdown(report: TonnageReport, config?: TonnageConfig): Promise<string>;
|
|
73
28
|
//#endregion
|
|
74
29
|
//#region src/run.d.ts
|
|
75
|
-
declare function runTonnage(config: TonnageConfig, options: {
|
|
30
|
+
export declare function runTonnage(config: TonnageConfig, options: {
|
|
76
31
|
configDirectory?: string;
|
|
77
32
|
mode: TonnageMode;
|
|
78
33
|
}): Promise<TonnageRunResult>;
|
|
79
34
|
//#endregion
|
|
80
|
-
export {
|
|
35
|
+
export type { BundleMeasurement, BundlePlatform, MeasureEntryOptions, MeasureImportsOptions, TonnageConfig, TonnageExports, TonnageMode, TonnageRecipe, TonnageRecipeRow, TonnageReport, TonnageRow, TonnageRunResult };
|
|
81
36
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/define-config.ts","../src/measure.ts","../src/readme.ts","../src/report.ts","../src/run.ts"],"mappings":";;;wBAEgB,aAAa,QAAQ,gBAAgB;;;KCKzC;EACX;EACA,WAAW;EACX;EACA;;KAGW,sBAAsB;wBAMZ,aACrB,eACA,SAAS,sBACP,QAAQ;wBAcW,eACrB,4BACA,SAAS,wBACP,QAAQ;;;wBCxCK,eAAe;EAC9B;EACA;;wBASe,uBACf,gBACA,kBACA;;;wBCUqB,oBACrB,QAAQ,eACR,0BACE,QAAQ;;wBAgEW,sBACrB,QAAQ,eACR,SAAQ,gBACN;;;wBCvFmB,WACrB,QAAQ,eACR;EACC;EACA,MAAM;IAEL,QAAQ"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as tonnageMarkers, r as updateGeneratedSection, t as runTonnage } from "./run-BJN1MXRf.mjs";
|
|
2
|
+
import { a as measureImports, i as measureEntry, n as renderTonnageMarkdown, t as createTonnageReport } from "./report-B3HrJ4UQ.mjs";
|
|
2
3
|
//#region src/define-config.ts
|
|
3
4
|
function defineConfig(config) {
|
|
4
5
|
return config;
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/define-config.ts"],"sourcesContent":["import type { TonnageConfig } from \"./types.ts\"\n\nexport function defineConfig(config: TonnageConfig): TonnageConfig {\n\treturn config\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/define-config.ts"],"sourcesContent":["import type { TonnageConfig } from \"./types.ts\"\n\nexport function defineConfig(config: TonnageConfig): TonnageConfig {\n\treturn config\n}\n"],"mappings":";;;AAEA,SAAgB,aAAa,QAAsC;CAClE,OAAO;AACR"}
|