@rollipop/rolldown-debug 1.0.8 → 1.0.10

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 ADDED
@@ -0,0 +1,101 @@
1
+ # @rolldown/debug
2
+
3
+ Utilities and generated TypeScript types for reading Rolldown devtools output.
4
+
5
+ When `devtools` is enabled, Rolldown writes JSON-lines files to:
6
+
7
+ ```text
8
+ node_modules/.rolldown/<session_id>/
9
+ meta.json
10
+ logs.json
11
+ ```
12
+
13
+ `logs.json` is complete after `await bundle.close()` resolves.
14
+
15
+ ## Parse Events
16
+
17
+ ```ts
18
+ import fs from 'node:fs';
19
+ import { parseToEvents, type Event, type StringRef } from '@rolldown/debug';
20
+
21
+ const data = fs.readFileSync('node_modules/.rolldown/<session_id>/logs.json', 'utf8');
22
+ const events = parseToEvents(data.trim());
23
+
24
+ type ActionEvent = Exclude<Event, StringRef> & { build_id: string };
25
+ const actionEvents = events.filter((event): event is ActionEvent => 'build_id' in event);
26
+ ```
27
+
28
+ Action events include `session_id`, `build_id`, `timestamp`, and an `action` discriminator. `StringRef` events contain deduplicated large string content and do not belong to a specific build.
29
+
30
+ ## Consume Package Data
31
+
32
+ Use `PackageGraphReady` to build a package table. In watch/rebuild sessions, `logs.json` is append-only, so select the events for the `build_id` being displayed.
33
+
34
+ ```ts
35
+ import fs from 'node:fs';
36
+ import { parseToEvents, type Event, type StringRef } from '@rolldown/debug';
37
+
38
+ type ActionEvent = Exclude<Event, StringRef> & { build_id: string };
39
+
40
+ function isActionEvent(event: Event): event is ActionEvent {
41
+ return 'build_id' in event;
42
+ }
43
+
44
+ const data = fs.readFileSync('node_modules/.rolldown/<session_id>/logs.json', 'utf8');
45
+ const actionEvents = parseToEvents(data.trim()).filter(isActionEvent);
46
+ const buildId = actionEvents.at(-1)?.build_id;
47
+
48
+ function latest<T extends ActionEvent['action']>(
49
+ action: T,
50
+ ): Extract<ActionEvent, { action: T }> | undefined {
51
+ for (let i = actionEvents.length - 1; i >= 0; i--) {
52
+ const event = actionEvents[i];
53
+ if (event.build_id === buildId && event.action === action) {
54
+ return event as Extract<ActionEvent, { action: T }>;
55
+ }
56
+ }
57
+ }
58
+
59
+ const packageGraph = latest('PackageGraphReady');
60
+ const chunkGraph = latest('ChunkGraphReady');
61
+ const moduleGraph = latest('ModuleGraphReady');
62
+
63
+ const chunksById = new Map(chunkGraph?.chunks.map((chunk) => [chunk.chunk_id, chunk]) ?? []);
64
+ const modulesById = new Map(moduleGraph?.modules.map((module) => [module.id, module]) ?? []);
65
+
66
+ const packageRows = packageGraph?.packages.map((pkg) => ({
67
+ id: pkg.package_id,
68
+ label: pkg.name ?? pkg.package_root,
69
+ version: pkg.version ?? 'unknown',
70
+ dependencyType: pkg.dependency_type,
71
+ renderedSize: pkg.size,
72
+ isUsed: pkg.is_used,
73
+ chunks: pkg.chunk_ids.flatMap((chunkId) => {
74
+ const chunk = chunksById.get(chunkId);
75
+ return chunk ? [chunk] : [];
76
+ }),
77
+ modules: pkg.modules.map(
78
+ (moduleId) =>
79
+ modulesById.get(moduleId) ?? {
80
+ id: moduleId,
81
+ },
82
+ ),
83
+ }));
84
+ ```
85
+
86
+ ## Package Fields
87
+
88
+ | Field | Consumer meaning |
89
+ | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
90
+ | `package_id` | Stable row key for one emitted package record. Prefer this, or `package_root`, over `name@version`. |
91
+ | `name` / `version` | Metadata from the resolved package manifest. Either can be `null`; fall back to `package_root` or an unknown version label in UI. |
92
+ | `package_root` | Package directory. Useful for display, duplicate detection, and row identity. |
93
+ | `is_used` | `true` when at least one module from the package appears in a generated chunk. `false` means the package was resolved but tree-shaken away. |
94
+ | `dependency_type` | `direct` when any package module is imported by a source module under the build `cwd` and outside `node_modules`; otherwise `transitive`. Rolldown does not inspect `package.json` dependency fields for this value. |
95
+ | `size` | Sum of rendered package module bytes after tree-shaking/codegen and before `renderChunk`, minification, banners, and final asset emission. This is package attribution data, not final asset size. |
96
+ | `modules` | Generated chunk module IDs for the package. Join with `ModuleGraphReady.modules[].id` when the module graph is needed. Empty for unused packages. |
97
+ | `chunk_ids` | IDs of chunks containing modules from the package. Join with `ChunkGraphReady.chunks[].chunk_id`. Empty for unused packages. |
98
+
99
+ To detect duplicate packages, group records by non-null `name`, then mark groups that contain more than one version or package root.
100
+
101
+ See `meta/design/devtools.md` in the Rolldown repository for implementation details and event lifecycle notes.
@@ -11,5 +11,6 @@ import type { HookResolveIdCallStart } from "./HookResolveIdCallStart";
11
11
  import type { HookTransformCallEnd } from "./HookTransformCallEnd";
12
12
  import type { HookTransformCallStart } from "./HookTransformCallStart";
13
13
  import type { ModuleGraphReady } from "./ModuleGraphReady";
14
+ import type { PackageGraphReady } from "./PackageGraphReady";
14
15
  import type { SessionMeta } from "./SessionMeta";
15
- export type Meta = HookTransformCallStart | HookTransformCallEnd | HookLoadCallStart | HookLoadCallEnd | BuildStart | BuildEnd | HookResolveIdCallStart | HookResolveIdCallEnd | ModuleGraphReady | SessionMeta | ChunkGraphReady | HookRenderChunkStart | HookRenderChunkEnd | AssetsReady;
16
+ export type Meta = HookTransformCallStart | HookTransformCallEnd | HookLoadCallStart | HookLoadCallEnd | BuildStart | BuildEnd | HookResolveIdCallStart | HookResolveIdCallEnd | ModuleGraphReady | SessionMeta | ChunkGraphReady | PackageGraphReady | HookRenderChunkStart | HookRenderChunkEnd | AssetsReady;
@@ -0,0 +1,5 @@
1
+ import type { PackageInfo } from "./PackageInfo";
2
+ export type PackageGraphReady = {
3
+ action: 'PackageGraphReady';
4
+ packages: Array<PackageInfo>;
5
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,12 @@
1
+ export type PackageInfo = {
2
+ package_id: string;
3
+ name: string | null;
4
+ version: string | null;
5
+ package_json_path: string;
6
+ package_root: string;
7
+ is_used: boolean;
8
+ dependency_type: 'direct' | 'transitive';
9
+ size: number;
10
+ modules: Array<string>;
11
+ chunk_ids: Array<number>;
12
+ };
@@ -0,0 +1,2 @@
1
+ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
2
+ export {};
@@ -18,5 +18,7 @@ export * from './Meta.js';
18
18
  export * from './Module.js';
19
19
  export * from './ModuleGraphReady.js';
20
20
  export * from './ModuleImport.js';
21
+ export * from './PackageGraphReady.js';
22
+ export * from './PackageInfo.js';
21
23
  export * from './PluginItem.js';
22
24
  export * from './SessionMeta.js';
@@ -18,5 +18,7 @@ export * from './Meta.js';
18
18
  export * from './Module.js';
19
19
  export * from './ModuleGraphReady.js';
20
20
  export * from './ModuleImport.js';
21
+ export * from './PackageGraphReady.js';
22
+ export * from './PackageInfo.js';
21
23
  export * from './PluginItem.js';
22
24
  export * from './SessionMeta.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rollipop/rolldown-debug",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "homepage": "https://rolldown.rs/",
5
5
  "license": "MIT",
6
6
  "repository": {