@abreen/tada 1.13.7 → 1.14.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 +46 -0
- package/build/generate-content-assets.ts +39 -185
- package/build/pipeline.ts +1 -1
- package/build/source-model.ts +2 -14
- package/build/types.d.ts +18 -18
- package/build/utils/html-comments.ts +3 -0
- package/build/utils/jdi-runner/TraceRunner.java +227 -38
- package/build/utils/markdown-partials.ts +235 -0
- package/build/utils/markdown.ts +12 -1
- package/build/utils/python-runner/trace_runner.py +58 -13
- package/build/utils/render.ts +14 -12
- package/build/utils/trace-core.ts +136 -14
- package/build/utils/trace-heap.ts +34 -0
- package/build/utils/trace-java.ts +60 -7
- package/build/utils/trace-layout.ts +58 -13
- package/build/utils/trace-python.ts +6 -2
- package/build/utils/trace-svg.ts +54 -60
- package/build/utils/trace.ts +193 -78
- package/build/watch/build-full.ts +26 -52
- package/build/watch/build-helpers.ts +66 -0
- package/build/watch/build-incremental.ts +32 -60
- package/build/watch/build-result.ts +19 -0
- package/build/watch/compiler-types.d.ts +2 -2
- package/build/watch/compiler.ts +30 -62
- package/build/watch/config-paths.ts +56 -0
- package/build/watch/engine.ts +199 -0
- package/{watch → build/watch}/fs-commit.ts +1 -3
- package/build/watch/index.ts +1 -1
- package/build/watch/mutations.ts +23 -25
- package/build/watch/planner.ts +14 -78
- package/build/watch/runtime.ts +26 -38
- package/build/watch/snapshot.ts +26 -47
- package/build/watch/types.d.ts +84 -0
- package/build/watch/validation.ts +1 -1
- package/init/content/lectures/02/_pr1.md +1 -1
- package/init/content/lectures/02/index.md +2 -2
- package/init/content/lectures/02/subdir/_foobar.md +3 -0
- package/init/content/lectures/02/subdir/_pr2.md +3 -3
- package/package.json +1 -2
- package/src/slides/index.ts +6 -2
- package/src/trace/index.ts +49 -12
- package/src/trace/style.scss +10 -0
- package/src/trace/types.d.ts +16 -4
- package/build/utils/include.ts +0 -57
- package/build/watch-reachability-state.ts +0 -305
- package/init/content/lectures/02/subdir/_foobar.html +0 -3
- package/watch/engine.ts +0 -296
- package/watch/events.ts +0 -10
- package/watch/types.d.ts +0 -103
package/README.md
CHANGED
|
@@ -40,6 +40,7 @@ A static site generator. The successor to Presto.
|
|
|
40
40
|
* `??? question ... ???` renders a Q & A section; answers hidden until click
|
|
41
41
|
* `+++ ... +++ ... +++` renders a two-column layout
|
|
42
42
|
* Special heading subtitles with `## Heading # A subtitle here`
|
|
43
|
+
* `{{{ _partial.md }}}` syntax for including partials
|
|
43
44
|
- Automatically generated favicon
|
|
44
45
|
* Text, color, font and font weight taken from config file
|
|
45
46
|
|
|
@@ -333,6 +334,51 @@ templates][lodash].
|
|
|
333
334
|
- Custom variables from the `"vars"` property of the config are available
|
|
334
335
|
under `vars` (e.g., `<%= vars.staffEmail %>`)
|
|
335
336
|
|
|
337
|
+
### Markdown partials
|
|
338
|
+
|
|
339
|
+
Use the `{{{ _partial.md }}}` syntax to include a partial (a fragment of
|
|
340
|
+
Markdown in a separate file whose name must start with `_`) at that particular
|
|
341
|
+
location in a Markdown file.
|
|
342
|
+
|
|
343
|
+
This is useful for reducing duplication across multiple documents which use the
|
|
344
|
+
exact same content, or for breaking up a large document into building blocks
|
|
345
|
+
which are easier to edit.
|
|
346
|
+
|
|
347
|
+
Partials are never built into their own pages, and they don't have front matter.
|
|
348
|
+
|
|
349
|
+
The `{{{ ... }}}` syntax is not a simple string replacement; instead, the
|
|
350
|
+
Markdown syntax tree of the partial is *added* to the syntax tree of the
|
|
351
|
+
Markdown file that includes it. This is a powerful feature because it allows you
|
|
352
|
+
to include content as a subtree.
|
|
353
|
+
|
|
354
|
+
For example, this partial `_groceries.md`
|
|
355
|
+
|
|
356
|
+
```
|
|
357
|
+
* apples
|
|
358
|
+
* oranges
|
|
359
|
+
* pears
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
can be inserted as a sub-list of a larger list in a Markdown page
|
|
363
|
+
|
|
364
|
+
```
|
|
365
|
+
title: To do list
|
|
366
|
+
|
|
367
|
+
* Grocery shopping
|
|
368
|
+
{{{ _groceries.md }}}
|
|
369
|
+
* Car wash
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
which results in:
|
|
373
|
+
|
|
374
|
+
```
|
|
375
|
+
* Grocery shopping
|
|
376
|
+
* apples
|
|
377
|
+
* oranges
|
|
378
|
+
* pears
|
|
379
|
+
* Car wash
|
|
380
|
+
```
|
|
381
|
+
|
|
336
382
|
|
|
337
383
|
[inter]: https://fonts.google.com/specimen/Inter
|
|
338
384
|
[lodash]: https://lodash.info/doc/template
|
|
@@ -6,16 +6,15 @@ import { createContentRecord } from './source-records';
|
|
|
6
6
|
import { validateConfigLinks } from './validate-config-links';
|
|
7
7
|
import { config, getConfigFileName } from './templates';
|
|
8
8
|
import { initHighlighter } from './utils/shiki-highlighter';
|
|
9
|
-
import { checkTraceToolAvailability
|
|
9
|
+
import { checkTraceToolAvailability } from './utils/trace';
|
|
10
10
|
import type {
|
|
11
11
|
SiteVariables,
|
|
12
12
|
ContentRenderOptions,
|
|
13
13
|
ContentRenderResult,
|
|
14
14
|
HtmlOutputAnalysis,
|
|
15
15
|
TraceToolAvailability,
|
|
16
|
-
WatchState,
|
|
17
16
|
} from './types';
|
|
18
|
-
import type {
|
|
17
|
+
import type { TraceCache } from './watch/compiler-types';
|
|
19
18
|
|
|
20
19
|
const log = makeLogger(import.meta.url);
|
|
21
20
|
|
|
@@ -25,152 +24,41 @@ function cloneHtmlOutputAnalysis(
|
|
|
25
24
|
return { outgoingTargets: new Set(analysis.outgoingTargets) };
|
|
26
25
|
}
|
|
27
26
|
|
|
27
|
+
function writeRecordOutputs(
|
|
28
|
+
distDir: string,
|
|
29
|
+
outputs: Map<string, string | Buffer>,
|
|
30
|
+
): void {
|
|
31
|
+
for (const [outputPath, content] of outputs) {
|
|
32
|
+
const outPath = path.join(distDir, outputPath);
|
|
33
|
+
fs.mkdirSync(path.dirname(outPath), { recursive: true });
|
|
34
|
+
fs.writeFileSync(outPath, content);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
28
38
|
export class ContentRenderer {
|
|
29
39
|
private siteVariables: SiteVariables;
|
|
30
|
-
private sourceFileCache: Map<string, TadaSourceRecord>;
|
|
31
|
-
private lastBuildFiles: Set<string>;
|
|
32
|
-
private javacAvailable: boolean | undefined;
|
|
33
40
|
private traceToolAvailability: TraceToolAvailability | undefined;
|
|
34
|
-
private traceCache: Map
|
|
35
|
-
string,
|
|
36
|
-
{
|
|
37
|
-
manifestUrl: string;
|
|
38
|
-
artifactId: string;
|
|
39
|
-
highlightedSource: string;
|
|
40
|
-
totalSteps: number;
|
|
41
|
-
mtime: number;
|
|
42
|
-
}
|
|
43
|
-
> = new Map();
|
|
41
|
+
private traceCache: TraceCache = new Map();
|
|
44
42
|
|
|
45
43
|
constructor(siteVariables: SiteVariables) {
|
|
46
44
|
this.siteVariables = siteVariables;
|
|
47
|
-
this.sourceFileCache = new Map();
|
|
48
|
-
this.lastBuildFiles = new Set();
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
private getCachedRecord(filePath: string): TadaSourceRecord | undefined {
|
|
52
|
-
return this.sourceFileCache.get(filePath);
|
|
53
45
|
}
|
|
54
46
|
|
|
55
47
|
async initHighlighter(): Promise<void> {
|
|
56
48
|
await initHighlighter(getRuntimeBundledShikiLanguages(this.siteVariables));
|
|
57
49
|
}
|
|
58
50
|
|
|
59
|
-
getDirtySourceFiles(
|
|
60
|
-
buildContentFiles: string[],
|
|
61
|
-
{ changedContentFiles, jsonDataChanged, partialsChanged }: WatchState = {},
|
|
62
|
-
): Set<string> {
|
|
63
|
-
if (
|
|
64
|
-
this.lastBuildFiles.size === 0 ||
|
|
65
|
-
!changedContentFiles ||
|
|
66
|
-
jsonDataChanged ||
|
|
67
|
-
partialsChanged
|
|
68
|
-
) {
|
|
69
|
-
return new Set(buildContentFiles);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// If any trace source changed, the trace cache will be stale, so rebuild
|
|
73
|
-
// all content pages to pick up the new trace output.
|
|
74
|
-
const traceFileChanged = [...changedContentFiles].some(isTraceSourceFile);
|
|
75
|
-
if (traceFileChanged) {
|
|
76
|
-
return new Set(buildContentFiles);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const buildFileSet = new Set(buildContentFiles);
|
|
80
|
-
const dirtySourceFiles = new Set<string>();
|
|
81
|
-
for (const filePath of changedContentFiles) {
|
|
82
|
-
if (buildFileSet.has(filePath)) {
|
|
83
|
-
dirtySourceFiles.add(filePath);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
return dirtySourceFiles;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
updateSourceCache(
|
|
90
|
-
filePath: string,
|
|
91
|
-
record: TadaSourceRecord,
|
|
92
|
-
changedOutputRelPaths: Set<string>,
|
|
93
|
-
removedOutputRelPaths: Set<string>,
|
|
94
|
-
changedHtmlAssetPaths: Set<string>,
|
|
95
|
-
removedHtmlAssetPaths: Set<string>,
|
|
96
|
-
): void {
|
|
97
|
-
const previousRecord = this.getCachedRecord(filePath);
|
|
98
|
-
const nextOutputPaths = new Set(record.outputs.keys());
|
|
99
|
-
|
|
100
|
-
for (const outputPath of previousRecord?.outputs.keys() ?? []) {
|
|
101
|
-
if (nextOutputPaths.has(outputPath)) {
|
|
102
|
-
continue;
|
|
103
|
-
}
|
|
104
|
-
removedOutputRelPaths.add(outputPath);
|
|
105
|
-
if (outputPath.endsWith('.html')) {
|
|
106
|
-
removedHtmlAssetPaths.add(outputPath);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
for (const outputPath of record.outputs.keys()) {
|
|
111
|
-
changedOutputRelPaths.add(outputPath);
|
|
112
|
-
if (outputPath.endsWith('.html')) {
|
|
113
|
-
changedHtmlAssetPaths.add(outputPath);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
this.sourceFileCache.set(filePath, record);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
writeCachedAssets(distDir: string, buildContentFiles: string[]): void {
|
|
121
|
-
for (const filePath of buildContentFiles) {
|
|
122
|
-
const record = this.getCachedRecord(filePath);
|
|
123
|
-
if (!record) {
|
|
124
|
-
continue;
|
|
125
|
-
}
|
|
126
|
-
for (const [outputPath, content] of record.outputs) {
|
|
127
|
-
const outPath = path.join(distDir, outputPath);
|
|
128
|
-
fs.mkdirSync(path.dirname(outPath), { recursive: true });
|
|
129
|
-
fs.writeFileSync(outPath, content);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
pruneRemovedSources(
|
|
135
|
-
buildFileSet: Set<string>,
|
|
136
|
-
removedOutputRelPaths: Set<string>,
|
|
137
|
-
removedHtmlAssetPaths: Set<string>,
|
|
138
|
-
): void {
|
|
139
|
-
for (const filePath of [...this.lastBuildFiles]) {
|
|
140
|
-
if (buildFileSet.has(filePath)) {
|
|
141
|
-
continue;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const previousRecord = this.getCachedRecord(filePath);
|
|
145
|
-
for (const outputPath of previousRecord?.outputs.keys() ?? []) {
|
|
146
|
-
removedOutputRelPaths.add(outputPath);
|
|
147
|
-
if (outputPath.endsWith('.html')) {
|
|
148
|
-
removedHtmlAssetPaths.add(outputPath);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
this.sourceFileCache.delete(filePath);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
51
|
processContent({
|
|
156
52
|
distDir,
|
|
157
53
|
assetFiles,
|
|
158
54
|
scan,
|
|
159
|
-
watchState,
|
|
160
55
|
}: ContentRenderOptions): ContentRenderResult {
|
|
161
56
|
const buildContentFiles = [...scan.buildContentFiles];
|
|
162
|
-
const buildFileSet = new Set<string>(buildContentFiles);
|
|
163
|
-
const dirtySourceFiles = this.getDirtySourceFiles(
|
|
164
|
-
buildContentFiles,
|
|
165
|
-
watchState,
|
|
166
|
-
);
|
|
167
|
-
const changedOutputRelPaths = new Set<string>();
|
|
168
|
-
const removedOutputRelPaths = new Set<string>();
|
|
169
|
-
const changedHtmlAssetPaths = new Set<string>();
|
|
170
|
-
const removedHtmlAssetPaths = new Set<string>();
|
|
171
57
|
const validInternalTargets = scan.validTargets;
|
|
172
58
|
|
|
173
59
|
const errors: Error[] = [];
|
|
60
|
+
const htmlAssetsByPath = new Map<string, string>();
|
|
61
|
+
const htmlAnalysisByPath = new Map<string, HtmlOutputAnalysis>();
|
|
174
62
|
|
|
175
63
|
const configLinkErrors = validateConfigLinks(
|
|
176
64
|
validInternalTargets,
|
|
@@ -185,29 +73,21 @@ export class ContentRenderer {
|
|
|
185
73
|
errors.push(new Error(msg));
|
|
186
74
|
}
|
|
187
75
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
removedHtmlAssetPaths,
|
|
192
|
-
);
|
|
193
|
-
|
|
194
|
-
if (dirtySourceFiles.size > 0) {
|
|
195
|
-
const noun = dirtySourceFiles.size === 1 ? 'file' : 'files';
|
|
196
|
-
log.info`Processing ${dirtySourceFiles.size} content ${noun}`;
|
|
76
|
+
if (buildContentFiles.length > 0) {
|
|
77
|
+
const noun = buildContentFiles.length === 1 ? 'file' : 'files';
|
|
78
|
+
log.info`Processing ${buildContentFiles.length} content ${noun}`;
|
|
197
79
|
}
|
|
198
80
|
|
|
199
|
-
if (this.
|
|
81
|
+
if (!this.traceToolAvailability && buildContentFiles.length > 0) {
|
|
200
82
|
this.traceToolAvailability = checkTraceToolAvailability();
|
|
201
|
-
|
|
202
|
-
if (!this.javacAvailable) {
|
|
83
|
+
if (!this.traceToolAvailability.java) {
|
|
203
84
|
log.warn`javac was not found; literate Java pages will not include execution output`;
|
|
204
85
|
}
|
|
205
86
|
}
|
|
206
87
|
|
|
207
|
-
for (const filePath of
|
|
208
|
-
let record: TadaSourceRecord;
|
|
88
|
+
for (const filePath of buildContentFiles) {
|
|
209
89
|
try {
|
|
210
|
-
record = createContentRecord({
|
|
90
|
+
const record = createContentRecord({
|
|
211
91
|
filePath,
|
|
212
92
|
siteVariables: this.siteVariables,
|
|
213
93
|
scan,
|
|
@@ -215,53 +95,27 @@ export class ContentRenderer {
|
|
|
215
95
|
outputDir: distDir,
|
|
216
96
|
traceCache: this.traceCache,
|
|
217
97
|
traceToolAvailability: this.traceToolAvailability,
|
|
218
|
-
skipLiterateJavaExecution: !this.
|
|
98
|
+
skipLiterateJavaExecution: !this.traceToolAvailability?.java,
|
|
219
99
|
});
|
|
100
|
+
writeRecordOutputs(distDir, record.outputs);
|
|
101
|
+
for (const [outputPath, content] of record.outputs) {
|
|
102
|
+
if (!outputPath.endsWith('.html') || typeof content !== 'string') {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
htmlAssetsByPath.set(outputPath, content);
|
|
106
|
+
const analysis = record.htmlAnalysisByOutputPath?.get(outputPath);
|
|
107
|
+
if (analysis) {
|
|
108
|
+
htmlAnalysisByPath.set(
|
|
109
|
+
outputPath,
|
|
110
|
+
cloneHtmlOutputAnalysis(analysis),
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
220
114
|
} catch (err) {
|
|
221
115
|
errors.push(err as Error);
|
|
222
|
-
continue;
|
|
223
|
-
}
|
|
224
|
-
this.updateSourceCache(
|
|
225
|
-
filePath,
|
|
226
|
-
record,
|
|
227
|
-
changedOutputRelPaths,
|
|
228
|
-
removedOutputRelPaths,
|
|
229
|
-
changedHtmlAssetPaths,
|
|
230
|
-
removedHtmlAssetPaths,
|
|
231
|
-
);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
this.writeCachedAssets(distDir, buildContentFiles);
|
|
235
|
-
this.lastBuildFiles = buildFileSet;
|
|
236
|
-
|
|
237
|
-
// Collect HTML asset content and analysis for Pagefind
|
|
238
|
-
const htmlAssetsByPath = new Map<string, string>();
|
|
239
|
-
const htmlAnalysisByPath = new Map<string, HtmlOutputAnalysis>();
|
|
240
|
-
for (const filePath of buildContentFiles) {
|
|
241
|
-
const record = this.getCachedRecord(filePath);
|
|
242
|
-
if (!record) {
|
|
243
|
-
continue;
|
|
244
|
-
}
|
|
245
|
-
for (const [outputPath, content] of record.outputs) {
|
|
246
|
-
if (!outputPath.endsWith('.html') || typeof content !== 'string') {
|
|
247
|
-
continue;
|
|
248
|
-
}
|
|
249
|
-
htmlAssetsByPath.set(outputPath, content);
|
|
250
|
-
const analysis = record.htmlAnalysisByOutputPath?.get(outputPath);
|
|
251
|
-
if (analysis) {
|
|
252
|
-
htmlAnalysisByPath.set(outputPath, cloneHtmlOutputAnalysis(analysis));
|
|
253
|
-
}
|
|
254
116
|
}
|
|
255
117
|
}
|
|
256
118
|
|
|
257
|
-
return {
|
|
258
|
-
errors,
|
|
259
|
-
changedHtmlAssetPaths,
|
|
260
|
-
removedHtmlAssetPaths,
|
|
261
|
-
removedOutputRelPaths,
|
|
262
|
-
htmlAssetsByPath,
|
|
263
|
-
htmlAnalysisByPath,
|
|
264
|
-
buildContentFiles,
|
|
265
|
-
};
|
|
119
|
+
return { errors, htmlAssetsByPath, htmlAnalysisByPath };
|
|
266
120
|
}
|
|
267
121
|
}
|
package/build/pipeline.ts
CHANGED
|
@@ -15,7 +15,7 @@ import { makeLogger, printFlair } from './log';
|
|
|
15
15
|
import { generateBuildManifest, getNextVersion } from './build-manifest';
|
|
16
16
|
import { scanProject } from './source-model';
|
|
17
17
|
import { validateConfig } from './watch/validation';
|
|
18
|
-
import { applyCommitPlan } from '
|
|
18
|
+
import { applyCommitPlan } from './watch/fs-commit';
|
|
19
19
|
import path from 'path';
|
|
20
20
|
|
|
21
21
|
const log = makeLogger(import.meta.url);
|
package/build/source-model.ts
CHANGED
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
normalizeOutputPath,
|
|
16
16
|
toPosix,
|
|
17
17
|
} from './utils/paths';
|
|
18
|
-
import type { ChangeBatch } from '
|
|
18
|
+
import type { ChangeBatch } from './watch/types';
|
|
19
19
|
import type { SiteVariables } from './types';
|
|
20
20
|
|
|
21
21
|
export interface TadaProjectScan {
|
|
@@ -34,18 +34,6 @@ export interface TadaProjectScan {
|
|
|
34
34
|
sourceTargetPaths: Map<string, Set<string>>;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
export interface TadaProjectScanSnapshotLike {
|
|
38
|
-
processedExts: Set<string>;
|
|
39
|
-
contentFiles: Set<string>;
|
|
40
|
-
buildContentFiles: Set<string>;
|
|
41
|
-
publicFiles: Set<string>;
|
|
42
|
-
literateJavaOutputPaths: Set<string>;
|
|
43
|
-
contentOwners: Map<string, string>;
|
|
44
|
-
publicOwners: Map<string, string>;
|
|
45
|
-
sourceOutputPaths: Map<string, Set<string>>;
|
|
46
|
-
sourceTargetPaths: Map<string, Set<string>>;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
37
|
export function shouldSkipContentFile(filePath: string): boolean {
|
|
50
38
|
const ext = path.extname(filePath).toLowerCase();
|
|
51
39
|
if (!(extensionIsMarkdown(ext) || ext === '.html')) {
|
|
@@ -333,7 +321,7 @@ export function scanProject(siteVariables: SiteVariables): TadaProjectScan {
|
|
|
333
321
|
}
|
|
334
322
|
|
|
335
323
|
export function updateProjectScan(
|
|
336
|
-
snapshot:
|
|
324
|
+
snapshot: TadaProjectScan,
|
|
337
325
|
batch: ChangeBatch,
|
|
338
326
|
): TadaProjectScan {
|
|
339
327
|
const scan = createEmptyScan(snapshot.processedExts);
|
package/build/types.d.ts
CHANGED
|
@@ -49,25 +49,13 @@ export interface ContentRenderOptions {
|
|
|
49
49
|
distDir: string;
|
|
50
50
|
assetFiles: string[];
|
|
51
51
|
scan: TadaProjectScan;
|
|
52
|
-
watchState?: WatchState;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/** State passed from watch mode to control incremental rebuilds */
|
|
56
|
-
export interface WatchState {
|
|
57
|
-
changedContentFiles?: Set<string>;
|
|
58
|
-
jsonDataChanged?: boolean;
|
|
59
|
-
partialsChanged?: boolean;
|
|
60
52
|
}
|
|
61
53
|
|
|
62
54
|
/** Result from ContentRenderer.processContent() */
|
|
63
55
|
export interface ContentRenderResult {
|
|
64
56
|
errors: Error[];
|
|
65
|
-
changedHtmlAssetPaths: Set<string>;
|
|
66
|
-
removedHtmlAssetPaths: Set<string>;
|
|
67
|
-
removedOutputRelPaths: Set<string>;
|
|
68
57
|
htmlAssetsByPath: Map<string, string>;
|
|
69
58
|
htmlAnalysisByPath: Map<string, HtmlOutputAnalysis>;
|
|
70
|
-
buildContentFiles: string[];
|
|
71
59
|
}
|
|
72
60
|
|
|
73
61
|
/** Logger returned by makeLogger() */
|
|
@@ -98,9 +86,9 @@ export interface RenderPlainTextOptions {
|
|
|
98
86
|
{
|
|
99
87
|
manifestUrl: string;
|
|
100
88
|
artifactId: string;
|
|
101
|
-
highlightedSource: string;
|
|
89
|
+
highlightedSources: { file: string; highlightedSource: string }[];
|
|
102
90
|
totalSteps: number;
|
|
103
|
-
|
|
91
|
+
sourceMtims: Record<string, number>;
|
|
104
92
|
}
|
|
105
93
|
>;
|
|
106
94
|
traceToolAvailability?: TraceToolAvailability;
|
|
@@ -218,7 +206,13 @@ export interface TraceStep {
|
|
|
218
206
|
file: string;
|
|
219
207
|
stack: TraceStackFrame[];
|
|
220
208
|
heap: Record<string, TraceHeapObject>;
|
|
221
|
-
|
|
209
|
+
output?: TraceOutputEvent[];
|
|
210
|
+
transientHeapRoots?: string[];
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export interface TraceOutputEvent {
|
|
214
|
+
stream: 'stdout' | 'stderr';
|
|
215
|
+
text: string;
|
|
222
216
|
}
|
|
223
217
|
|
|
224
218
|
export interface TraceStackFrame {
|
|
@@ -244,13 +238,18 @@ export type TraceValue =
|
|
|
244
238
|
export type TraceHeapObject =
|
|
245
239
|
| { type: string; elements: TraceValue[] }
|
|
246
240
|
| { type: string; fields: Record<string, TraceValue> }
|
|
247
|
-
| { type: string; value: string };
|
|
241
|
+
| { type: string; value: string | number | boolean };
|
|
248
242
|
|
|
249
243
|
/** Manifest written alongside trace chunks */
|
|
250
244
|
export interface TraceManifest {
|
|
251
245
|
totalSteps: number;
|
|
252
246
|
chunkSize: number;
|
|
253
|
-
|
|
247
|
+
primaryFile: string;
|
|
248
|
+
sources: TraceSource[];
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export interface TraceSource {
|
|
252
|
+
file: string;
|
|
254
253
|
source: string;
|
|
255
254
|
lineToSteps: Record<number, number[]>;
|
|
256
255
|
}
|
|
@@ -279,8 +278,9 @@ export interface TraceLayout {
|
|
|
279
278
|
|
|
280
279
|
/** A single entry in a chunk file (new format with precomputed SVG). */
|
|
281
280
|
export interface TraceChunkEntry {
|
|
281
|
+
file: string;
|
|
282
282
|
line: number;
|
|
283
|
-
|
|
283
|
+
output?: TraceOutputEvent[];
|
|
284
284
|
svg: string;
|
|
285
285
|
}
|
|
286
286
|
|