@abreen/tada 1.17.0 → 1.18.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.
Files changed (107) hide show
  1. package/README.md +41 -7
  2. package/bin/tada.ts +23 -9
  3. package/bin/validators.ts +34 -1
  4. package/build/branding.ts +41 -0
  5. package/build/build-manifest.ts +10 -5
  6. package/build/{watch/compiler-types.d.ts → build-types.d.ts} +8 -5
  7. package/build/build-validation.ts +176 -0
  8. package/build/bundle.ts +75 -65
  9. package/build/columns-plugin.ts +27 -1
  10. package/build/config-loader.ts +3 -3
  11. package/build/custom-fonts.ts +8 -5
  12. package/build/deflist-id-plugin.ts +2 -2
  13. package/build/generate-favicon.ts +7 -6
  14. package/build/generate-fonts.ts +8 -15
  15. package/build/generate-katex-assets.ts +19 -17
  16. package/build/generate-web-app-manifest.ts +3 -11
  17. package/build/lodash-template.ts +14 -0
  18. package/build/output-publication.ts +238 -0
  19. package/build/pagefind.ts +49 -21
  20. package/build/pdf-text.ts +41 -1
  21. package/build/pipeline.ts +95 -101
  22. package/build/site-assets.ts +46 -0
  23. package/build/site-build.ts +267 -0
  24. package/build/source-model.ts +223 -229
  25. package/build/source-records.ts +69 -81
  26. package/build/template-globals.ts +3 -0
  27. package/build/templates.ts +12 -8
  28. package/build/toc-plugin.ts +21 -21
  29. package/build/types.d.ts +38 -38
  30. package/build/util.ts +0 -4
  31. package/build/utils/code.ts +51 -117
  32. package/build/utils/final-html.ts +171 -47
  33. package/build/utils/jdi-runner/LiterateRunner.java +9 -1
  34. package/build/utils/literate-java.ts +11 -7
  35. package/build/utils/markdown-partials.ts +4 -3
  36. package/build/utils/markdown.ts +6 -17
  37. package/build/utils/paths.ts +3 -0
  38. package/build/utils/plain-text.ts +18 -0
  39. package/build/utils/render.ts +197 -154
  40. package/build/utils/shiki-highlighter.ts +11 -0
  41. package/build/utils/source-template.ts +2 -2
  42. package/build/utils/trace-core.ts +8 -83
  43. package/build/utils/trace.ts +38 -95
  44. package/build/validate-config-links.ts +39 -6
  45. package/build/watch/build-incremental.ts +46 -103
  46. package/build/watch/compiler.ts +158 -37
  47. package/build/watch/engine.ts +207 -162
  48. package/build/watch/index.ts +9 -2
  49. package/build/watch/planner.ts +88 -144
  50. package/build/watch/runtime.ts +21 -34
  51. package/build/watch/types.d.ts +32 -64
  52. package/package.json +4 -5
  53. package/schema/site.schema.json +18 -2
  54. package/src/_content.scss +447 -0
  55. package/src/_fonts.scss +90 -0
  56. package/src/_layout.scss +50 -35
  57. package/src/appearance-picker/{style.scss → _index.scss} +1 -1
  58. package/src/code/{style.scss → _index.scss} +61 -0
  59. package/src/header/{_base.scss → _index.scss} +98 -6
  60. package/src/index.ts +1 -17
  61. package/src/navigate/{style.scss → _index.scss} +20 -0
  62. package/src/navigate/eligible.ts +0 -40
  63. package/src/navigate/index.ts +50 -5
  64. package/src/navigate/lifecycle.ts +19 -2
  65. package/src/navigate/runtime.ts +20 -4
  66. package/src/page-update/index.ts +33 -20
  67. package/src/print/{style.scss → _index.scss} +3 -1
  68. package/src/search/index.ts +30 -2
  69. package/src/slides/{style.scss → _index.scss} +5 -0
  70. package/src/style.scss +24 -536
  71. package/src/timezone/index.ts +29 -3
  72. package/src/timezone/time-format.ts +4 -0
  73. package/src/toc/index.ts +6 -5
  74. package/src/trace/index.ts +11 -1
  75. package/templates/_author.html +2 -2
  76. package/templates/_download.html +1 -1
  77. package/templates/_footer.html +1 -1
  78. package/templates/_heading.html +3 -3
  79. package/templates/_nav.html +2 -2
  80. package/templates/_page-bottom.html +6 -0
  81. package/templates/_top.html +18 -14
  82. package/templates/code.html +22 -21
  83. package/templates/default.html +12 -11
  84. package/templates/literate.html +6 -5
  85. package/build/copy.ts +0 -82
  86. package/build/generate-content-assets.ts +0 -121
  87. package/build/utils/content-files.ts +0 -170
  88. package/build/watch/assets.ts +0 -103
  89. package/build/watch/build-full.ts +0 -97
  90. package/build/watch/build-helpers.ts +0 -66
  91. package/build/watch/build-result.ts +0 -19
  92. package/build/watch/fs-commit.ts +0 -153
  93. package/build/watch/mutations.ts +0 -73
  94. package/build/watch/snapshot.ts +0 -201
  95. package/build/watch/validation.ts +0 -50
  96. package/src/code.scss +0 -60
  97. package/src/critical.scss +0 -5
  98. package/src/header/style.scss +0 -91
  99. /package/src/{literate.scss → _literate.scss} +0 -0
  100. /package/src/{material-symbols.scss → _material-symbols.scss} +0 -0
  101. /package/src/anchor/{style.scss → _index.scss} +0 -0
  102. /package/src/page-update/{style.scss → _index.scss} +0 -0
  103. /package/src/question/{style.scss → _index.scss} +0 -0
  104. /package/src/search/{style.scss → _index.scss} +0 -0
  105. /package/src/timezone/{style.scss → _index.scss} +0 -0
  106. /package/src/toc/{style.scss → _index.scss} +0 -0
  107. /package/src/trace/{style.scss → _index.scss} +0 -0
@@ -1,6 +1,4 @@
1
- import fs from 'fs';
2
1
  import path from 'path';
3
- import { getExtensionToShikiLanguage } from './site-variables';
4
2
  import {
5
3
  renderCodePageAsset,
6
4
  renderCopiedContentAsset,
@@ -8,41 +6,41 @@ import {
8
6
  renderPlainTextPageAsset,
9
7
  toPosix,
10
8
  } from './util';
11
- import { extensionIsMarkdown, isLiterateJava } from './utils/file-types';
12
9
  import type {
13
10
  Asset,
11
+ OutputContent,
12
+ HtmlOutputAnalysis,
14
13
  RenderDependencyCollector,
15
14
  SiteVariables,
16
15
  TraceToolAvailability,
17
16
  } from './types';
18
17
  import type { TadaProjectScan } from './source-model';
19
- import {
20
- collectSourceHtmlAnalysis,
21
- collectSourceOutputs,
22
- type TadaSourceRecord,
23
- } from './watch/snapshot';
24
- import type { TraceCache } from './watch/compiler-types';
25
18
 
26
- export type TadaSourceRenderKind =
27
- | 'skip'
28
- | 'plain-text-page'
29
- | 'literate-java'
30
- | 'code-page'
31
- | 'content-copy'
32
- | 'public-copy';
19
+ import type { TraceCache } from './build-types';
20
+
21
+ export interface TadaSourceRecord {
22
+ sourcePath: string;
23
+ kind: 'content' | 'public';
24
+ outputs: Map<string, OutputContent>;
25
+ htmlAnalysisByOutputPath?: Map<string, HtmlOutputAnalysis>;
26
+ partialDeps: Set<string>;
27
+ traceDeps: Set<string>;
28
+ internalTargets: Set<string>;
29
+ authorKey?: string;
30
+ }
33
31
 
34
32
  function createDependencyCollector(): {
35
33
  collector: RenderDependencyCollector;
36
34
  partials: Set<string>;
37
35
  traceFiles: Set<string>;
38
36
  internalTargets: Set<string>;
39
- generatedOutputPaths: Set<string>;
37
+ traceOutputs: Map<string, string>;
40
38
  authorKey: string | undefined;
41
39
  } {
42
40
  const partials = new Set<string>();
43
41
  const traceFiles = new Set<string>();
44
42
  const internalTargets = new Set<string>();
45
- const generatedOutputPaths = new Set<string>();
43
+ const traceOutputs = new Map<string, string>();
46
44
  let authorKey: string | undefined;
47
45
 
48
46
  return {
@@ -50,7 +48,7 @@ function createDependencyCollector(): {
50
48
  partials,
51
49
  traceFiles,
52
50
  internalTargets,
53
- generatedOutputPaths,
51
+ traceOutputs,
54
52
  setAuthorKey(value: string) {
55
53
  authorKey = value;
56
54
  },
@@ -58,7 +56,7 @@ function createDependencyCollector(): {
58
56
  partials,
59
57
  traceFiles,
60
58
  internalTargets,
61
- generatedOutputPaths,
59
+ traceOutputs,
62
60
  get authorKey() {
63
61
  return authorKey;
64
62
  },
@@ -74,7 +72,6 @@ function createEmptyContentRecord(filePath: string): TadaSourceRecord {
74
72
  partialDeps: new Set(),
75
73
  traceDeps: new Set(),
76
74
  internalTargets: new Set(),
77
- generatedOutputPaths: new Set(),
78
75
  };
79
76
  }
80
77
 
@@ -82,79 +79,31 @@ function createRawContentAsset(filePath: string, contentDir: string): Asset[] {
82
79
  return [
83
80
  {
84
81
  assetPath: toPosix(path.relative(contentDir, filePath)),
85
- content: fs.readFileSync(filePath),
82
+ content: { copyFrom: filePath },
86
83
  },
87
84
  ];
88
85
  }
89
86
 
90
- export function classifySourceRenderKind({
91
- filePath,
92
- scan,
93
- siteVariables,
94
- }: {
95
- filePath: string;
96
- scan: TadaProjectScan;
97
- siteVariables: SiteVariables;
98
- }): TadaSourceRenderKind {
99
- if (scan.publicFiles.has(filePath)) {
100
- return 'public-copy';
101
- }
102
-
103
- if (!scan.contentFiles.has(filePath)) {
104
- return 'skip';
105
- }
106
-
107
- const ext = path.extname(filePath).slice(1).toLowerCase();
108
- const lowerExt = path.extname(filePath).toLowerCase();
109
- if (!scan.processedExts.has(ext)) {
110
- return 'content-copy';
111
- }
112
-
113
- if (!scan.buildContentFiles.has(filePath)) {
114
- return 'skip';
115
- }
116
-
117
- if (isLiterateJava(filePath)) {
118
- return 'literate-java';
119
- }
120
-
121
- if (extensionIsMarkdown(lowerExt) || lowerExt === '.html') {
122
- return 'plain-text-page';
123
- }
124
-
125
- if (Object.hasOwn(getExtensionToShikiLanguage(siteVariables), ext)) {
126
- return 'code-page';
127
- }
128
-
129
- return 'skip';
130
- }
131
-
132
87
  export function createContentRecord({
133
88
  filePath,
134
89
  siteVariables,
135
90
  scan,
136
91
  assetFiles,
137
- outputDir,
92
+ isWatchMode,
138
93
  traceCache,
139
94
  traceToolAvailability,
140
- cachedTraceSourceDir,
141
95
  skipLiterateJavaExecution,
142
96
  }: {
143
97
  filePath: string;
144
98
  siteVariables: SiteVariables;
145
99
  scan: TadaProjectScan;
146
100
  assetFiles: string[];
147
- outputDir: string;
101
+ isWatchMode: boolean;
148
102
  traceCache?: TraceCache;
149
103
  traceToolAvailability?: TraceToolAvailability;
150
- cachedTraceSourceDir?: string;
151
104
  skipLiterateJavaExecution?: boolean;
152
105
  }): TadaSourceRecord {
153
- const renderKind = classifySourceRenderKind({
154
- filePath,
155
- scan,
156
- siteVariables,
157
- });
106
+ const renderKind = scan.sources.get(filePath)?.renderKind ?? 'skip';
158
107
  if (renderKind === 'skip' || renderKind === 'public-copy') {
159
108
  return createEmptyContentRecord(filePath);
160
109
  }
@@ -168,11 +117,13 @@ export function createContentRecord({
168
117
  ...renderLiterateJavaPageAsset({
169
118
  filePath,
170
119
  contentDir: scan.contentDir,
171
- distDir: outputDir,
172
120
  siteVariables,
173
121
  assetFiles,
122
+ isWatchMode,
174
123
  skipExecution: skipLiterateJavaExecution,
175
124
  validInternalTargets: scan.validTargets,
125
+ generatedPageTargets: scan.generatedPageTargets,
126
+ codePageSourceTargets: scan.codePageSourceTargets,
176
127
  literateJavaOutputPaths: scan.literateJavaOutputPaths,
177
128
  dependencyCollector: deps.collector,
178
129
  }),
@@ -183,13 +134,14 @@ export function createContentRecord({
183
134
  ...renderPlainTextPageAsset({
184
135
  filePath,
185
136
  contentDir: scan.contentDir,
186
- distDir: outputDir,
187
137
  siteVariables,
188
138
  validInternalTargets: scan.validTargets,
139
+ generatedPageTargets: scan.generatedPageTargets,
140
+ codePageSourceTargets: scan.codePageSourceTargets,
189
141
  assetFiles,
142
+ isWatchMode,
190
143
  literateJavaOutputPaths: scan.literateJavaOutputPaths,
191
144
  dependencyCollector: deps.collector,
192
- cachedTraceSourceDir,
193
145
  traceCache,
194
146
  traceToolAvailability,
195
147
  }),
@@ -200,10 +152,12 @@ export function createContentRecord({
200
152
  ...renderCodePageAsset({
201
153
  filePath,
202
154
  contentDir: scan.contentDir,
203
- distDir: outputDir,
204
155
  siteVariables,
205
156
  validInternalTargets: scan.validTargets,
157
+ generatedPageTargets: scan.generatedPageTargets,
158
+ codePageSourceTargets: scan.codePageSourceTargets,
206
159
  assetFiles,
160
+ isWatchMode,
207
161
  literateJavaOutputPaths: scan.literateJavaOutputPaths,
208
162
  dependencyCollector: deps.collector,
209
163
  }),
@@ -224,12 +178,11 @@ export function createContentRecord({
224
178
  return {
225
179
  sourcePath: filePath,
226
180
  kind: 'content',
227
- outputs: collectSourceOutputs(assets, deps.generatedOutputPaths, outputDir),
181
+ outputs: collectSourceOutputs(assets, deps.traceOutputs),
228
182
  htmlAnalysisByOutputPath: collectSourceHtmlAnalysis(assets),
229
183
  partialDeps: deps.partials,
230
184
  traceDeps: deps.traceFiles,
231
185
  internalTargets: deps.internalTargets,
232
- generatedOutputPaths: deps.generatedOutputPaths,
233
186
  authorKey: deps.authorKey,
234
187
  };
235
188
  }
@@ -242,11 +195,46 @@ export function createPublicRecord(
242
195
  return {
243
196
  sourcePath: filePath,
244
197
  kind: 'public',
245
- outputs: new Map([[relPath, fs.readFileSync(filePath)]]),
198
+ outputs: new Map([[relPath, { copyFrom: filePath }]]),
246
199
  htmlAnalysisByOutputPath: new Map(),
247
200
  partialDeps: new Set(),
248
201
  traceDeps: new Set(),
249
202
  internalTargets: new Set(),
250
- generatedOutputPaths: new Set(),
251
203
  };
252
204
  }
205
+
206
+ export function collectSourceOutputs(
207
+ assets: Asset[],
208
+ traceOutputs: ReadonlyMap<string, string>,
209
+ ): Map<string, OutputContent> {
210
+ const outputs = new Map<string, OutputContent>();
211
+ for (const asset of assets) {
212
+ outputs.set(asset.assetPath, asset.content);
213
+ }
214
+ for (const [outputPath, content] of traceOutputs) {
215
+ outputs.set(outputPath, content);
216
+ }
217
+ return outputs;
218
+ }
219
+
220
+ function cloneHtmlOutputAnalysis(
221
+ analysis: HtmlOutputAnalysis,
222
+ ): HtmlOutputAnalysis {
223
+ return { outgoingTargets: new Set(analysis.outgoingTargets) };
224
+ }
225
+
226
+ export function collectSourceHtmlAnalysis(
227
+ assets: Asset[],
228
+ ): Map<string, HtmlOutputAnalysis> {
229
+ const htmlAnalysisByOutputPath = new Map<string, HtmlOutputAnalysis>();
230
+ for (const asset of assets) {
231
+ if (!asset.assetPath.endsWith('.html') || !asset.htmlAnalysis) {
232
+ continue;
233
+ }
234
+ htmlAnalysisByOutputPath.set(
235
+ asset.assetPath,
236
+ cloneHtmlOutputAnalysis(asset.htmlAnalysis),
237
+ );
238
+ }
239
+ return htmlAnalysisByOutputPath;
240
+ }
@@ -1,3 +1,4 @@
1
+ import { encodePublicAssetPath } from './custom-fonts';
1
2
  import timezones from '../src/timezone/timezones.json' with { type: 'json' };
2
3
  import type { SiteVariables } from './types';
3
4
 
@@ -24,6 +25,7 @@ interface TemplateGlobals {
24
25
  classNames: (obj: Record<string, unknown>) => string;
25
26
  cx: (obj: Record<string, unknown>) => string;
26
27
  encodeAuthoredUrl: (value: string) => string;
28
+ encodePublicAssetPath: (value: string) => string;
27
29
  renderTimeZoneChooser: () => string;
28
30
  }
29
31
 
@@ -53,6 +55,7 @@ export default function createTemplateGlobals(
53
55
  classNames,
54
56
  cx: classNames,
55
57
  encodeAuthoredUrl,
58
+ encodePublicAssetPath,
56
59
  renderTimeZoneChooser,
57
60
  };
58
61
  }
@@ -1,6 +1,6 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
- import _ from 'lodash';
3
+ import { compileTemplate } from './lodash-template';
4
4
  import {
5
5
  PROJECT_CONFIG_NAMES,
6
6
  getProjectConfigBaseName,
@@ -53,7 +53,7 @@ export function getConfigFileName(name: ProjectConfigName): string | undefined {
53
53
  export function render(
54
54
  fileName: string,
55
55
  params?: Record<string, unknown> | null,
56
- ): string | undefined {
56
+ ): string {
57
57
  if (params != null) {
58
58
  // Allow the template to call render(), it will use our params
59
59
  params.render = (otherFileName: string) => render(otherFileName, params);
@@ -64,20 +64,24 @@ export function render(
64
64
 
65
65
  renderStack.push(fileName);
66
66
  try {
67
- return _.template(templates[fileName])(params ?? undefined);
67
+ if (!Object.hasOwn(templates, fileName)) {
68
+ throw new Error(`Unknown template "${fileName}"`);
69
+ }
70
+ return compileTemplate(templates[fileName])(params ?? undefined);
68
71
  } catch (err) {
69
72
  if (errorStack == null) {
70
73
  errorStack = renderStack.slice();
71
-
72
- if (renderStack.length > 1) {
73
- throw err;
74
- }
75
- } else if (renderStack.length === 1) {
74
+ }
75
+ if (renderStack.length === 1) {
76
76
  const topItem = errorStack[errorStack.length - 1];
77
77
  throw new Error(`Render error in ${topItem}: ${err}`, { cause: err });
78
78
  }
79
+ throw err;
79
80
  } finally {
80
81
  renderStack.pop();
82
+ if (renderStack.length === 0) {
83
+ errorStack = null;
84
+ }
81
85
  }
82
86
  }
83
87
 
@@ -1,6 +1,7 @@
1
1
  import type MarkdownIt from 'markdown-it';
2
2
  import { convertMarkdown as curlyQuote } from 'quote-quote';
3
3
  import type { JavaTocEntry } from './types';
4
+ import textToId, { deduplicateId } from './text-to-id';
4
5
 
5
6
  interface HeadingItem {
6
7
  kind: 'heading';
@@ -17,7 +18,7 @@ interface AlertItem {
17
18
  kind: 'alert';
18
19
  type: string;
19
20
  title: string;
20
- id?: string;
21
+ id: string;
21
22
  }
22
23
 
23
24
  type TocItem = HeadingItem | DinkusItem | AlertItem;
@@ -31,6 +32,7 @@ export function tocPlugin(md: MarkdownIt): void {
31
32
  const tokens = state.tokens;
32
33
  const items: TocItem[] = [];
33
34
  const containerStack: string[] = [];
35
+ const usedAlertIds = new Map<string, number>();
34
36
 
35
37
  for (let i = 0; i < tokens.length; i++) {
36
38
  const token = tokens[i];
@@ -70,19 +72,22 @@ export function tocPlugin(md: MarkdownIt): void {
70
72
  const depth = containerStack.length;
71
73
  const parentIsSection = depth === 1 && containerStack[0] === 'section';
72
74
 
73
- if (depth === 0 || parentIsSection) {
74
- const match = token.info
75
- .trim()
76
- .match(/^(note|warning)(?:\s+"(.+)"|\s+(.+))?$/);
77
- if (match) {
78
- const type = match[1];
79
- let title = (match[2] || match[3])?.trim();
80
- if (title) {
81
- title = md.utils.escapeHtml(curlyQuote(title));
82
- } else {
83
- title = type === 'warning' ? 'Warning' : 'Note';
84
- }
85
- items.push({ kind: 'alert', type, title });
75
+ const match = token.info
76
+ .trim()
77
+ .match(/^(note|warning)(?:\s+"(.+)"|\s+(.+))?$/);
78
+ if (match) {
79
+ const type = match[1];
80
+ const title = (match[2] || match[3])?.trim();
81
+ // Assign IDs to every alert, including those excluded from the TOC.
82
+ const id = deduplicateId(usedAlertIds, textToId(title || type));
83
+ token.attrSet('id', id);
84
+ if (depth === 0 || parentIsSection) {
85
+ const displayTitle = title
86
+ ? md.utils.escapeHtml(curlyQuote(title))
87
+ : type === 'warning'
88
+ ? 'Warning'
89
+ : 'Note';
90
+ items.push({ kind: 'alert', type, title: displayTitle, id });
86
91
  }
87
92
  }
88
93
  // Fall through to push 'alert' onto container stack
@@ -110,16 +115,12 @@ export function tocPlugin(md: MarkdownIt): void {
110
115
  });
111
116
  }
112
117
 
113
- export function generateTocHtml(
114
- tocItems: TocItem[],
115
- alertIds: string[],
116
- ): string {
118
+ export function generateTocHtml(tocItems: TocItem[]): string {
117
119
  if (!tocItems || tocItems.length === 0) {
118
120
  return '';
119
121
  }
120
122
 
121
123
  let lastHeadingLevel = 1;
122
- let alertIdx = 0;
123
124
  const parts = ['<ol>'];
124
125
 
125
126
  for (const item of tocItems) {
@@ -139,8 +140,7 @@ export function generateTocHtml(
139
140
 
140
141
  if (item.kind === 'alert') {
141
142
  const level = lastHeadingLevel + 1;
142
- const id = alertIds[alertIdx++];
143
- const href = `#${id}`;
143
+ const href = `#${item.id}`;
144
144
  parts.push(
145
145
  `<li class="alert-item level${level} ${item.type}">` +
146
146
  `<a href="${href}">${item.title}</a></li>`,
package/build/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { BundledLanguage } from 'shiki';
2
- import type { TadaProjectScan } from './source-model';
2
+ import type { TraceCache } from './build-types';
3
3
 
4
4
  export type PlainTextLanguage = 'text' | 'txt' | 'plain';
5
5
 
@@ -18,7 +18,7 @@ export interface SerifMonoFontTuning {
18
18
  }
19
19
 
20
20
  export interface FontFamilyOverride<Tuning = unknown> {
21
- regular: string;
21
+ regular?: string;
22
22
  italic?: string;
23
23
  bold?: string;
24
24
  boldItalic?: string;
@@ -40,6 +40,8 @@ export interface SiteVariables {
40
40
  banner?: string;
41
41
  symbol?: string;
42
42
  faviconSymbol?: string;
43
+ logo?: string;
44
+ favicon?: string;
43
45
  themeColor: string;
44
46
  faviconColor?: string;
45
47
  faviconFontWeight?: number;
@@ -71,24 +73,18 @@ export interface HtmlOutputAnalysis {
71
73
  outgoingTargets: Set<string>;
72
74
  }
73
75
 
74
- export interface Asset {
75
- assetPath: string;
76
- content: string | Buffer;
77
- htmlAnalysis?: HtmlOutputAnalysis;
76
+ /** An output copied unchanged from a source file when it is written */
77
+ export interface CopiedFile {
78
+ copyFrom: string;
78
79
  }
79
80
 
80
- /** Options for the content rendering pipeline */
81
- export interface ContentRenderOptions {
82
- distDir: string;
83
- assetFiles: string[];
84
- scan: TadaProjectScan;
85
- }
81
+ /** Output content: rendered text or bytes, or a reference to a file to copy */
82
+ export type OutputContent = string | Uint8Array | CopiedFile;
86
83
 
87
- /** Result from ContentRenderer.processContent() */
88
- export interface ContentRenderResult {
89
- errors: Error[];
90
- htmlAssetsByPath: Map<string, string>;
91
- htmlAnalysisByPath: Map<string, HtmlOutputAnalysis>;
84
+ export interface Asset {
85
+ assetPath: string;
86
+ content: OutputContent;
87
+ htmlAnalysis?: HtmlOutputAnalysis;
92
88
  }
93
89
 
94
90
  /** Logger returned by makeLogger() */
@@ -107,23 +103,15 @@ export interface Logger {
107
103
  export interface RenderPlainTextOptions {
108
104
  filePath: string;
109
105
  contentDir: string;
110
- distDir: string;
111
106
  siteVariables: SiteVariables;
112
- validInternalTargets: Set<string>;
107
+ validInternalTargets: ReadonlySet<string>;
108
+ generatedPageTargets?: ReadonlySet<string>;
109
+ codePageSourceTargets?: ReadonlySet<string>;
113
110
  assetFiles: string[];
114
- literateJavaOutputPaths?: Set<string>;
111
+ isWatchMode: boolean;
112
+ literateJavaOutputPaths?: ReadonlySet<string>;
115
113
  dependencyCollector?: RenderDependencyCollector;
116
- cachedTraceSourceDir?: string;
117
- traceCache?: Map<
118
- string,
119
- {
120
- manifestUrl: string;
121
- artifactId: string;
122
- highlightedSources: { file: string; highlightedSource: string }[];
123
- totalSteps: number;
124
- sourceMtims: Record<string, number>;
125
- }
126
- >;
114
+ traceCache?: TraceCache;
127
115
  traceToolAvailability?: TraceToolAvailability;
128
116
  }
129
117
 
@@ -136,11 +124,13 @@ export interface TraceToolAvailability {
136
124
  export interface RenderCodePageOptions {
137
125
  filePath: string;
138
126
  contentDir: string;
139
- distDir: string;
140
127
  siteVariables: SiteVariables;
141
128
  assetFiles: string[];
142
- validInternalTargets: Set<string>;
143
- literateJavaOutputPaths?: Set<string>;
129
+ isWatchMode: boolean;
130
+ validInternalTargets: ReadonlySet<string>;
131
+ generatedPageTargets?: ReadonlySet<string>;
132
+ codePageSourceTargets?: ReadonlySet<string>;
133
+ literateJavaOutputPaths?: ReadonlySet<string>;
144
134
  dependencyCollector?: RenderDependencyCollector;
145
135
  }
146
136
 
@@ -148,12 +138,14 @@ export interface RenderCodePageOptions {
148
138
  export interface RenderLiterateJavaOptions {
149
139
  filePath: string;
150
140
  contentDir: string;
151
- distDir: string;
152
141
  siteVariables: SiteVariables;
153
142
  assetFiles: string[];
143
+ isWatchMode: boolean;
154
144
  skipExecution?: boolean;
155
- validInternalTargets: Set<string>;
156
- literateJavaOutputPaths?: Set<string>;
145
+ validInternalTargets: ReadonlySet<string>;
146
+ generatedPageTargets?: ReadonlySet<string>;
147
+ codePageSourceTargets?: ReadonlySet<string>;
148
+ literateJavaOutputPaths?: ReadonlySet<string>;
157
149
  dependencyCollector?: RenderDependencyCollector;
158
150
  }
159
151
 
@@ -168,7 +160,8 @@ export interface RenderDependencyCollector {
168
160
  partials?: Set<string>;
169
161
  traceFiles?: Set<string>;
170
162
  internalTargets?: Set<string>;
171
- generatedOutputPaths?: Set<string>;
163
+ /** Files a page generates besides its own assets, by output path */
164
+ traceOutputs?: Map<string, string>;
172
165
  setAuthorKey?: (authorKey: string) => void;
173
166
  }
174
167
 
@@ -287,6 +280,13 @@ export interface TraceSource {
287
280
  lineToSteps: Record<number, number[]>;
288
281
  }
289
282
 
283
+ /** A generated trace manifest or chunk file */
284
+ export interface TraceArtifactFile {
285
+ /** File name inside the trace's `sha256-*` artifact directory */
286
+ name: string;
287
+ content: string;
288
+ }
289
+
290
290
  /** Position and size of a heap object in the precomputed layout. */
291
291
  export interface TraceObjectLayout {
292
292
  x: number;
package/build/util.ts CHANGED
@@ -1,10 +1,6 @@
1
- export { getFilesByExtensions } from './utils/content-files';
2
1
  export {
3
2
  createApplyBasePath,
4
- getContentDir,
5
3
  getDistDir,
6
- getPackageDir,
7
- getPublicDir,
8
4
  normalizeOutputPath,
9
5
  toPosix,
10
6
  } from './utils/paths';