@abreen/tada 1.13.4 → 1.13.9

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.
@@ -42,6 +42,7 @@ export interface TraceContext {
42
42
 
43
43
  export interface TraceResult {
44
44
  manifestUrl: string;
45
+ artifactId: string;
45
46
  highlightedSource: string;
46
47
  totalSteps: number;
47
48
  mtime: number;
@@ -141,6 +142,7 @@ export function createTraceHelpers(context: TraceContext): {
141
142
  const outputPaths = getTraceOutputPaths(
142
143
  relDir,
143
144
  traceName,
145
+ cached.artifactId,
144
146
  cached.totalSteps,
145
147
  );
146
148
  if (
@@ -155,7 +157,12 @@ export function createTraceHelpers(context: TraceContext): {
155
157
  }
156
158
  return {
157
159
  ...cached,
158
- manifestUrl: buildManifestUrl({ relDir, traceName, applyBasePath }),
160
+ manifestUrl: buildManifestUrl({
161
+ relDir,
162
+ traceName,
163
+ artifactId: cached.artifactId,
164
+ applyBasePath,
165
+ }),
159
166
  };
160
167
  }
161
168
  }
@@ -176,32 +183,42 @@ export function createTraceHelpers(context: TraceContext): {
176
183
  );
177
184
  const traceOutputDir = path.join(distDir, relDir, '_traces', traceName);
178
185
 
179
- const manifest = chunkTraceOutput(
186
+ const traceOutput = chunkTraceOutput(
180
187
  output,
181
188
  traceOutputDir,
189
+ relDir,
190
+ traceName,
182
191
  sourceFileNameForTrace(sourceFile),
183
192
  source,
184
193
  { chunkSize: DEFAULT_CHUNK_SIZE, ignoreFields },
185
194
  );
186
- for (const outputPath of getTraceOutputPaths(
187
- relDir,
188
- traceName,
189
- manifest.totalSteps,
190
- )) {
195
+ for (const outputPath of traceOutput.outputPaths) {
191
196
  dependencyCollector?.generatedOutputPaths?.add(outputPath);
192
197
  }
193
198
 
194
- const manifestUrl = buildManifestUrl({ relDir, traceName, applyBasePath });
199
+ const manifestUrl = buildManifestUrl({
200
+ relDir,
201
+ traceName,
202
+ artifactId: traceOutput.artifactId,
203
+ applyBasePath,
204
+ });
195
205
 
196
- const totalSteps = manifest.totalSteps;
206
+ const totalSteps = traceOutput.manifest.totalSteps;
197
207
  const mtime = fs.statSync(sourceFilePath).mtimeMs;
198
208
  cache.set(sourceFilePath, {
199
209
  manifestUrl,
210
+ artifactId: traceOutput.artifactId,
200
211
  highlightedSource,
201
212
  totalSteps,
202
213
  mtime,
203
214
  });
204
- return { manifestUrl, highlightedSource, totalSteps, mtime };
215
+ return {
216
+ manifestUrl,
217
+ artifactId: traceOutput.artifactId,
218
+ highlightedSource,
219
+ totalSteps,
220
+ mtime,
221
+ };
205
222
  }
206
223
 
207
224
  return {
@@ -1,6 +1,6 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
- import { bundle } from '../bundle';
3
+ import { bundle, getBundleNaming } from '../bundle';
4
4
  import { copyFonts } from '../generate-fonts';
5
5
  import { copyKatexAssets } from '../generate-katex-assets';
6
6
  import { generateFavicons } from '../generate-favicon';
@@ -42,7 +42,7 @@ export async function bundleWatchAssets(
42
42
  const reloadAssets = await Bun.build({
43
43
  entrypoints: [RELOAD_CLIENT_PATH],
44
44
  outdir: outputDir,
45
- naming: '[name].bundle.[ext]',
45
+ naming: getBundleNaming(),
46
46
  sourcemap: 'inline',
47
47
  });
48
48
  return [
@@ -1,34 +1,24 @@
1
1
  import { compileTemplates, config } from '../templates';
2
2
  import { getDevSiteVariables } from '../site-variables';
3
- import { createContentRecord, createPublicRecord } from '../source-records';
4
3
  import { getDistDir } from '../util';
5
- import type { CompilerBuildResult } from '../../watch/types';
6
- import {
7
- collectHtmlAnalysisByPath,
8
- collectHtmlAssetsByPath,
9
- createSnapshot,
10
- type TadaSourceRecord,
11
- type TadaSnapshot,
12
- } from './snapshot';
4
+ import type { CompilerBuildResult } from './types';
5
+ import { createSnapshot, type TadaSourceRecord } from './snapshot';
13
6
  import { scanProject } from '../source-model';
14
- import type {
15
- TadaBuildMeta,
16
- TraceCache,
17
- WatchTraceOptions,
18
- } from './compiler-types';
7
+ import type { TraceCache, WatchTraceOptions } from './compiler-types';
19
8
  import {
20
9
  bundleWatchAssets,
21
10
  ensureHighlighter,
22
11
  makeTempBuildDir,
23
12
  populateStaticAssets,
24
13
  removeDirIfExists,
25
- writeAssets,
26
14
  } from './assets';
15
+ import { validateConfig, validateProjectConfigLinks } from './validation';
16
+ import { buildFailedFromError, buildSucceeded } from './build-result';
27
17
  import {
28
- diagnosticsFromMessages,
29
- validateConfig,
30
- validateProjectConfigLinks,
31
- } from './validation';
18
+ buildFailedWithDiagnostics,
19
+ renderContentRecord,
20
+ renderPublicRecord,
21
+ } from './build-helpers';
32
22
 
33
23
  export async function buildFull({
34
24
  traceCache,
@@ -36,7 +26,7 @@ export async function buildFull({
36
26
  }: {
37
27
  traceCache: TraceCache;
38
28
  traceOptions: WatchTraceOptions;
39
- }): Promise<CompilerBuildResult<TadaSnapshot, TadaBuildMeta>> {
29
+ }): Promise<CompilerBuildResult> {
40
30
  const distDir = getDistDir();
41
31
  const outputDir = makeTempBuildDir(distDir);
42
32
  try {
@@ -44,8 +34,7 @@ export async function buildFull({
44
34
  const scan = scanProject(siteVariables);
45
35
  const configDiagnostics = validateConfig(scan);
46
36
  if (configDiagnostics.length > 0) {
47
- removeDirIfExists(outputDir);
48
- return { ok: false, diagnostics: configDiagnostics };
37
+ return buildFailedWithDiagnostics(outputDir, configDiagnostics);
49
38
  }
50
39
 
51
40
  compileTemplates(siteVariables);
@@ -56,33 +45,34 @@ export async function buildFull({
56
45
 
57
46
  const contentRecords = new Map<string, TadaSourceRecord>();
58
47
  for (const filePath of scan.contentFiles) {
59
- const record = createContentRecord({
48
+ const record = renderContentRecord({
60
49
  filePath,
61
50
  siteVariables,
62
51
  scan,
63
52
  assetFiles,
64
53
  outputDir,
65
54
  traceCache,
66
- traceToolAvailability: traceOptions.toolAvailability,
55
+ traceOptions,
67
56
  cachedTraceSourceDir: distDir,
68
57
  });
69
- if (record.outputs.size > 0) {
70
- writeAssets(outputDir, record.outputs);
58
+ if (record) {
71
59
  contentRecords.set(filePath, record);
72
60
  }
73
61
  }
74
62
 
75
63
  const publicRecords = new Map<string, TadaSourceRecord>();
76
64
  for (const filePath of scan.publicFiles) {
77
- const record = createPublicRecord(filePath, scan.publicDir);
78
- writeAssets(outputDir, record.outputs);
65
+ const record = renderPublicRecord({
66
+ filePath,
67
+ publicDir: scan.publicDir,
68
+ outputDir,
69
+ });
79
70
  publicRecords.set(filePath, record);
80
71
  }
81
72
 
82
73
  const linkDiagnostics = validateProjectConfigLinks(scan.validTargets);
83
74
  if (linkDiagnostics.length > 0) {
84
- removeDirIfExists(outputDir);
85
- return { ok: false, diagnostics: linkDiagnostics };
75
+ return buildFailedWithDiagnostics(outputDir, linkDiagnostics);
86
76
  }
87
77
 
88
78
  const nextSnapshot = createSnapshot({
@@ -95,29 +85,13 @@ export async function buildFull({
95
85
  publicRecords,
96
86
  });
97
87
 
98
- return {
99
- ok: true,
100
- snapshot: nextSnapshot,
101
- commit: {
102
- kind: 'replace-root',
103
- stagedPath: outputDir,
104
- targetPath: distDir,
105
- },
106
- meta: {
107
- htmlAssetsByPath: collectHtmlAssetsByPath(nextSnapshot.contentRecords),
108
- htmlAnalysisByPath: collectHtmlAnalysisByPath(
109
- nextSnapshot.contentRecords,
110
- ),
111
- siteVariables,
112
- },
113
- };
88
+ return buildSucceeded(nextSnapshot, {
89
+ kind: 'replace-root',
90
+ stagedPath: outputDir,
91
+ targetPath: distDir,
92
+ });
114
93
  } catch (error) {
115
94
  removeDirIfExists(outputDir);
116
- return {
117
- ok: false,
118
- diagnostics: diagnosticsFromMessages([
119
- error instanceof Error ? error.message : String(error),
120
- ]),
121
- };
95
+ return buildFailedFromError(error);
122
96
  }
123
97
  }
@@ -0,0 +1,66 @@
1
+ import { createContentRecord, createPublicRecord } from '../source-records';
2
+ import type { SiteVariables } from '../types';
3
+ import type { TadaProjectScan, TadaSourceRecord } from './snapshot';
4
+ import type { CompilerBuildResult, WatchDiagnostic } from './types';
5
+ import type { TraceCache, WatchTraceOptions } from './compiler-types';
6
+ import { removeDirIfExists, writeAssets } from './assets';
7
+
8
+ export function buildFailedWithDiagnostics(
9
+ outputDir: string,
10
+ diagnostics: WatchDiagnostic[],
11
+ ): CompilerBuildResult {
12
+ removeDirIfExists(outputDir);
13
+ return { ok: false, diagnostics };
14
+ }
15
+
16
+ export function renderContentRecord({
17
+ filePath,
18
+ siteVariables,
19
+ scan,
20
+ assetFiles,
21
+ outputDir,
22
+ traceCache,
23
+ traceOptions,
24
+ cachedTraceSourceDir,
25
+ }: {
26
+ filePath: string;
27
+ siteVariables: SiteVariables;
28
+ scan: TadaProjectScan;
29
+ assetFiles: string[];
30
+ outputDir: string;
31
+ traceCache: TraceCache;
32
+ traceOptions: WatchTraceOptions;
33
+ cachedTraceSourceDir: string;
34
+ }): TadaSourceRecord | undefined {
35
+ const record = createContentRecord({
36
+ filePath,
37
+ siteVariables,
38
+ scan,
39
+ assetFiles,
40
+ outputDir,
41
+ traceCache,
42
+ traceToolAvailability: traceOptions.toolAvailability,
43
+ cachedTraceSourceDir,
44
+ });
45
+ if (record.outputs.size === 0) {
46
+ return undefined;
47
+ }
48
+ writeAssets(outputDir, record.outputs);
49
+ return record;
50
+ }
51
+
52
+ export function renderPublicRecord({
53
+ filePath,
54
+ publicDir,
55
+ outputDir,
56
+ }: {
57
+ filePath: string;
58
+ publicDir: string;
59
+ outputDir?: string;
60
+ }): TadaSourceRecord {
61
+ const record = createPublicRecord(filePath, publicDir);
62
+ if (outputDir) {
63
+ writeAssets(outputDir, record.outputs);
64
+ }
65
+ return record;
66
+ }
@@ -1,32 +1,23 @@
1
1
  import { compileTemplates, config } from '../templates';
2
2
  import { getDistDir } from '../util';
3
- import { createContentRecord, createPublicRecord } from '../source-records';
4
- import type { CompilerBuildResult } from '../../watch/types';
5
- import type {
6
- TadaBuildMeta,
7
- TraceCache,
8
- WatchTraceOptions,
9
- } from './compiler-types';
10
- import type { TadaWatchPlan } from './planner';
11
- import {
12
- collectHtmlAnalysisByPath,
13
- collectHtmlAssetsByPath,
14
- createSnapshot,
15
- type TadaSnapshot,
16
- } from './snapshot';
3
+ import type { CompilerBuildResult } from './types';
4
+ import type { TraceCache, WatchTraceOptions } from './compiler-types';
5
+ import type { TadaIncrementalWatchPlan } from './planner';
6
+ import { createSnapshot, type TadaSnapshot } from './snapshot';
17
7
  import {
18
8
  copyExistingBuildAssets,
19
9
  ensureHighlighter,
20
10
  makeTempBuildDir,
21
11
  removeDirIfExists,
22
- writeAssets,
23
12
  } from './assets';
24
13
  import { computeMutations } from './mutations';
14
+ import { validateConfig, validateProjectConfigLinks } from './validation';
15
+ import { buildFailedFromError, buildSucceeded } from './build-result';
25
16
  import {
26
- diagnosticsFromMessages,
27
- validateConfig,
28
- validateProjectConfigLinks,
29
- } from './validation';
17
+ buildFailedWithDiagnostics,
18
+ renderContentRecord,
19
+ renderPublicRecord,
20
+ } from './build-helpers';
30
21
 
31
22
  export async function buildIncremental({
32
23
  plan,
@@ -34,23 +25,23 @@ export async function buildIncremental({
34
25
  traceCache,
35
26
  traceOptions,
36
27
  }: {
37
- plan: TadaWatchPlan;
28
+ plan: TadaIncrementalWatchPlan;
38
29
  snapshot: TadaSnapshot;
39
30
  traceCache: TraceCache;
40
31
  traceOptions: WatchTraceOptions;
41
- }): Promise<CompilerBuildResult<TadaSnapshot, TadaBuildMeta>> {
42
- const outputDir = makeTempBuildDir(plan.scan.distDir);
32
+ }): Promise<CompilerBuildResult> {
33
+ const distDir = getDistDir();
34
+ const outputDir = makeTempBuildDir(distDir);
43
35
  try {
44
36
  const siteVariables = snapshot.siteVariables;
45
37
  const configDiagnostics = validateConfig(plan.scan);
46
38
  if (configDiagnostics.length > 0) {
47
- removeDirIfExists(outputDir);
48
- return { ok: false, diagnostics: configDiagnostics };
39
+ return buildFailedWithDiagnostics(outputDir, configDiagnostics);
49
40
  }
50
41
 
51
42
  compileTemplates(siteVariables);
52
43
  await ensureHighlighter(siteVariables);
53
- copyExistingBuildAssets(getDistDir(), outputDir, snapshot.assetFiles);
44
+ copyExistingBuildAssets(distDir, outputDir, snapshot.assetFiles);
54
45
 
55
46
  const nextContentRecords = new Map(snapshot.contentRecords);
56
47
  const nextPublicRecords = new Map(snapshot.publicRecords);
@@ -64,25 +55,27 @@ export async function buildIncremental({
64
55
 
65
56
  for (const sourcePath of plan.contentToRender) {
66
57
  nextContentRecords.delete(sourcePath);
67
- const record = createContentRecord({
58
+ const record = renderContentRecord({
68
59
  filePath: sourcePath,
69
60
  siteVariables,
70
61
  scan: plan.scan,
71
62
  assetFiles: snapshot.assetFiles,
72
63
  outputDir,
73
64
  traceCache,
74
- traceToolAvailability: traceOptions.toolAvailability,
75
- cachedTraceSourceDir: getDistDir(),
65
+ traceOptions,
66
+ cachedTraceSourceDir: distDir,
76
67
  });
77
- if (record.outputs.size > 0) {
78
- writeAssets(outputDir, record.outputs);
68
+ if (record) {
79
69
  nextContentRecords.set(sourcePath, record);
80
70
  }
81
71
  }
82
72
 
83
73
  for (const sourcePath of plan.publicToRender) {
84
74
  nextPublicRecords.delete(sourcePath);
85
- const record = createPublicRecord(sourcePath, plan.scan.publicDir);
75
+ const record = renderPublicRecord({
76
+ filePath: sourcePath,
77
+ publicDir: plan.scan.publicDir,
78
+ });
86
79
  nextPublicRecords.set(sourcePath, record);
87
80
  }
88
81
 
@@ -97,11 +90,10 @@ export async function buildIncremental({
97
90
  });
98
91
 
99
92
  const linkDiagnostics = validateProjectConfigLinks(
100
- nextSnapshot.validTargets,
93
+ nextSnapshot.scan.validTargets,
101
94
  );
102
95
  if (linkDiagnostics.length > 0) {
103
- removeDirIfExists(outputDir);
104
- return { ok: false, diagnostics: linkDiagnostics };
96
+ return buildFailedWithDiagnostics(outputDir, linkDiagnostics);
105
97
  }
106
98
 
107
99
  const forceSourcePaths = new Set([
@@ -112,35 +104,15 @@ export async function buildIncremental({
112
104
  snapshot,
113
105
  nextSnapshot,
114
106
  forceSourcePaths,
115
- ).map(mutation =>
116
- mutation.kind === 'write'
117
- ? {
118
- kind: 'write' as const,
119
- path: mutation.path,
120
- content: mutation.content!,
121
- }
122
- : { kind: 'delete' as const, path: mutation.path },
123
107
  );
124
108
  removeDirIfExists(outputDir);
125
- return {
126
- ok: true,
127
- snapshot: nextSnapshot,
128
- commit: { kind: 'apply-mutations', rootDir: getDistDir(), mutations },
129
- meta: {
130
- htmlAssetsByPath: collectHtmlAssetsByPath(nextSnapshot.contentRecords),
131
- htmlAnalysisByPath: collectHtmlAnalysisByPath(
132
- nextSnapshot.contentRecords,
133
- ),
134
- siteVariables,
135
- },
136
- };
109
+ return buildSucceeded(nextSnapshot, {
110
+ kind: 'apply-mutations',
111
+ rootDir: distDir,
112
+ mutations,
113
+ });
137
114
  } catch (error) {
138
115
  removeDirIfExists(outputDir);
139
- return {
140
- ok: false,
141
- diagnostics: diagnosticsFromMessages([
142
- error instanceof Error ? error.message : String(error),
143
- ]),
144
- };
116
+ return buildFailedFromError(error);
145
117
  }
146
118
  }
@@ -0,0 +1,19 @@
1
+ import type { CommitPlan, CompilerBuildResult } from './types';
2
+ import { createBuildMeta, type TadaSnapshot } from './snapshot';
3
+ import { diagnosticsFromMessages } from './validation';
4
+
5
+ export function buildSucceeded(
6
+ snapshot: TadaSnapshot,
7
+ commit: CommitPlan,
8
+ ): CompilerBuildResult {
9
+ return { ok: true, snapshot, commit, meta: createBuildMeta(snapshot) };
10
+ }
11
+
12
+ export function buildFailedFromError(error: unknown): CompilerBuildResult {
13
+ return {
14
+ ok: false,
15
+ diagnostics: diagnosticsFromMessages([
16
+ error instanceof Error ? error.message : String(error),
17
+ ]),
18
+ };
19
+ }
@@ -6,6 +6,7 @@ import type {
6
6
 
7
7
  export interface TraceCacheEntry {
8
8
  manifestUrl: string;
9
+ artifactId: string;
9
10
  highlightedSource: string;
10
11
  totalSteps: number;
11
12
  mtime: number;
@@ -1,30 +1,20 @@
1
1
  import path from 'path';
2
- import {
3
- getProjectConfigBaseName,
4
- getSiteConfigBaseName,
5
- getSupportedConfigFilePaths,
6
- } from '../config-files';
7
- import { getDevSiteVariables } from '../site-variables';
8
2
  import { getProjectConfigDir } from '../templates';
9
3
  import { getContentDir, getPublicDir } from '../util';
10
4
  import type {
11
5
  ChangeBatch,
12
6
  CompilerBuildResult,
13
- CompilerPlanResult,
14
7
  WatchCompiler,
15
8
  WatchTarget,
16
- } from '../../watch/types';
9
+ } from './types';
17
10
  import { buildFull } from './build-full';
18
11
  import { buildIncremental } from './build-incremental';
19
- import type {
20
- TadaBuildMeta,
21
- TraceCache,
22
- WatchTraceOptions,
23
- } from './compiler-types';
12
+ import type { TraceCache, WatchTraceOptions } from './compiler-types';
24
13
  import { checkTraceToolAvailability, isTraceSourceFile } from '../utils/trace';
25
- import { createTadaWatchPlan, type TadaWatchPlan } from './planner';
26
- import { scanProject, updateProjectScan } from '../source-model';
14
+ import { createTadaWatchPlan } from './planner';
15
+ import { updateProjectScan } from '../source-model';
27
16
  import type { TadaSnapshot } from './snapshot';
17
+ import { getWatchConfigFilePaths } from './config-paths';
28
18
 
29
19
  export function invalidateTraceCacheForBatch(
30
20
  traceCache: TraceCache,
@@ -38,11 +28,7 @@ export function invalidateTraceCacheForBatch(
38
28
  }
39
29
  }
40
30
 
41
- export class TadaWatchCompiler implements WatchCompiler<
42
- TadaSnapshot,
43
- TadaWatchPlan,
44
- TadaBuildMeta
45
- > {
31
+ export class TadaWatchCompiler implements WatchCompiler {
46
32
  private traceCache: TraceCache;
47
33
  private traceOptions: WatchTraceOptions;
48
34
 
@@ -55,23 +41,11 @@ export class TadaWatchCompiler implements WatchCompiler<
55
41
  const contentDir = getContentDir();
56
42
  const publicDir = getPublicDir();
57
43
  const projectConfigDir = path.resolve(getProjectConfigDir());
58
- const configFilePaths = new Set([
59
- ...getSupportedConfigFilePaths('.', getSiteConfigBaseName('dev')).map(
60
- filePath => path.resolve(filePath),
61
- ),
62
- ...getSupportedConfigFilePaths(
63
- projectConfigDir,
64
- getProjectConfigBaseName('nav'),
65
- ).map(filePath => path.resolve(filePath)),
66
- ...getSupportedConfigFilePaths(
67
- projectConfigDir,
68
- getProjectConfigBaseName('authors'),
69
- ).map(filePath => path.resolve(filePath)),
70
- ]);
44
+ const configFilePaths = getWatchConfigFilePaths();
71
45
 
72
46
  return [
73
- { path: contentDir },
74
- { path: publicDir },
47
+ { path: contentDir, chokidar: { usePolling: true } },
48
+ { path: publicDir, chokidar: { usePolling: true } },
75
49
  {
76
50
  path: projectConfigDir,
77
51
  chokidar: { depth: 0 },
@@ -80,34 +54,24 @@ export class TadaWatchCompiler implements WatchCompiler<
80
54
  ];
81
55
  }
82
56
 
83
- async buildInitial(): Promise<
84
- CompilerBuildResult<TadaSnapshot, TadaBuildMeta>
85
- > {
86
- return buildFull({
87
- traceCache: this.traceCache,
88
- traceOptions: this.traceOptions,
89
- });
90
- }
91
-
92
- async plan(
57
+ async build(
93
58
  snapshot: TadaSnapshot | undefined,
94
- batch: ChangeBatch,
95
- ): Promise<CompilerPlanResult<TadaWatchPlan>> {
96
- invalidateTraceCacheForBatch(this.traceCache, batch);
97
- const scan = snapshot
98
- ? updateProjectScan(snapshot, batch)
99
- : scanProject(getDevSiteVariables());
100
- return {
101
- kind: 'build',
102
- plan: createTadaWatchPlan({ snapshot, batch, scan }),
103
- };
104
- }
59
+ batch?: ChangeBatch,
60
+ ): Promise<CompilerBuildResult> {
61
+ if (batch) {
62
+ invalidateTraceCacheForBatch(this.traceCache, batch);
63
+ }
105
64
 
106
- async run(
107
- plan: TadaWatchPlan,
108
- snapshot: TadaSnapshot | undefined,
109
- ): Promise<CompilerBuildResult<TadaSnapshot, TadaBuildMeta>> {
110
- if (plan.kind === 'full' || !snapshot) {
65
+ if (!snapshot || !batch) {
66
+ return buildFull({
67
+ traceCache: this.traceCache,
68
+ traceOptions: this.traceOptions,
69
+ });
70
+ }
71
+
72
+ const scan = updateProjectScan(snapshot.scan, batch);
73
+ const plan = createTadaWatchPlan({ snapshot, batch, scan });
74
+ if (plan.kind === 'full') {
111
75
  return buildFull({
112
76
  traceCache: this.traceCache,
113
77
  traceOptions: this.traceOptions,
@@ -0,0 +1,56 @@
1
+ import path from 'path';
2
+ import {
3
+ getProjectConfigBaseName,
4
+ getSiteConfigBaseName,
5
+ getSupportedConfigFilePaths,
6
+ } from '../config-files';
7
+ import { getProjectConfigDir } from '../templates';
8
+
9
+ export type WatchConfigPathKind = 'site' | 'nav' | 'authors';
10
+
11
+ function getConfigPathEntries(): Array<{
12
+ kind: WatchConfigPathKind;
13
+ paths: string[];
14
+ }> {
15
+ const projectConfigDir = getProjectConfigDir();
16
+ return [
17
+ {
18
+ kind: 'site',
19
+ paths: getSupportedConfigFilePaths('.', getSiteConfigBaseName('dev')),
20
+ },
21
+ {
22
+ kind: 'nav',
23
+ paths: getSupportedConfigFilePaths(
24
+ projectConfigDir,
25
+ getProjectConfigBaseName('nav'),
26
+ ),
27
+ },
28
+ {
29
+ kind: 'authors',
30
+ paths: getSupportedConfigFilePaths(
31
+ projectConfigDir,
32
+ getProjectConfigBaseName('authors'),
33
+ ),
34
+ },
35
+ ];
36
+ }
37
+
38
+ function getWatchConfigPathKinds(): Map<string, WatchConfigPathKind> {
39
+ return new Map(
40
+ getConfigPathEntries().flatMap(entry =>
41
+ entry.paths.map(
42
+ filePath => [path.resolve(filePath), entry.kind] as const,
43
+ ),
44
+ ),
45
+ );
46
+ }
47
+
48
+ export function getWatchConfigFilePaths(): Set<string> {
49
+ return new Set(getWatchConfigPathKinds().keys());
50
+ }
51
+
52
+ export function classifyWatchConfigPath(
53
+ filePath: string,
54
+ ): WatchConfigPathKind | undefined {
55
+ return getWatchConfigPathKinds().get(path.resolve(filePath));
56
+ }