@mintlify/previewing 4.0.1216 → 4.0.1218
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.
|
@@ -11,6 +11,7 @@ import pathUtil from 'path';
|
|
|
11
11
|
import { CMD_EXEC_PATH, NEXT_PROPS_PATH, NEXT_PUBLIC_PATH, CLIENT_PATH } from '../../constants.js';
|
|
12
12
|
import { addChangeLog, addErrorLog, clearErrorLogs, getCurrentErrorLogs, } from '../../logging-state.js';
|
|
13
13
|
import { AddedLog, DeletedLog, EditedLog, WarningLog, InfoLog, ErrorLog } from '../../logs.js';
|
|
14
|
+
import { reportPageCompileError, reportPageCompileSuccess } from '../on-demand-page.js';
|
|
14
15
|
import { clearDocsConfigCaches, getDocsConfigApiHash, getDocsConfigNavigationHash, getVariablesHash, hasDocsConfigApiChanged, hasDocsConfigNavigationChanged, hasNavigationApiReference, hasDocsConfigVariablesChanged, updateDocsConfigHashCache, } from './docs-config-cache.js';
|
|
15
16
|
import { generateDependentSnippets } from './generateDependentSnippets.js';
|
|
16
17
|
import { generatePagesWithImports } from './generatePagesWithImports.js';
|
|
@@ -154,6 +155,9 @@ const onUnlinkEvent = async (filename, triggerRefresh, options) => {
|
|
|
154
155
|
const potentialCategory = getFileCategory(filename, { importedFiles });
|
|
155
156
|
frontmatterHashes.delete(filename);
|
|
156
157
|
removePageMetadataCacheEntryForFile(filename);
|
|
158
|
+
if (potentialCategory === 'page') {
|
|
159
|
+
reportPageCompileSuccess(filename);
|
|
160
|
+
}
|
|
157
161
|
if (hasTrackedReferencedFile(filename)) {
|
|
158
162
|
try {
|
|
159
163
|
const { mintConfig, openApiFiles, docsConfig } = await getDocsState(handleParseError);
|
|
@@ -359,16 +363,36 @@ const onUpdateEvent = async (filename, triggerRefresh, options = {}) => {
|
|
|
359
363
|
case 'page': {
|
|
360
364
|
let contentStr = (await readFile(filePath)).toString();
|
|
361
365
|
regenerateNavFromPageMetadataCache = await shouldRegenerateNavForPage(filename, contentStr, frontmatterHashes, handleParseError);
|
|
362
|
-
|
|
363
|
-
const
|
|
364
|
-
|
|
365
|
-
|
|
366
|
+
let pageFailed = false;
|
|
367
|
+
const capturePageError = () => {
|
|
368
|
+
pageFailed = true;
|
|
369
|
+
};
|
|
370
|
+
const capturePageErrorAndLog = (message) => {
|
|
371
|
+
pageFailed = true;
|
|
372
|
+
handleParseError(message);
|
|
373
|
+
};
|
|
374
|
+
try {
|
|
375
|
+
const tree = await preparseMdxTree(contentStr, CMD_EXEC_PATH, filePath, capturePageError);
|
|
376
|
+
const importsResponse = await findAndRemoveImports(tree);
|
|
377
|
+
if (hasImports(importsResponse)) {
|
|
378
|
+
contentStr = stringifyTree(await resolvePageImports({ ...importsResponse, filename }));
|
|
379
|
+
}
|
|
380
|
+
const { pageContent, pageMetadata, slug } = await createPage(filename, contentStr, CMD_EXEC_PATH, [], [], capturePageErrorAndLog);
|
|
381
|
+
await fse.outputFile(targetPath, pageContent, {
|
|
382
|
+
flag: 'w',
|
|
383
|
+
});
|
|
384
|
+
upsertPageMetadataCacheEntry(slug, pageMetadata);
|
|
385
|
+
}
|
|
386
|
+
catch (error) {
|
|
387
|
+
reportPageCompileError(filename);
|
|
388
|
+
throw error;
|
|
389
|
+
}
|
|
390
|
+
if (pageFailed) {
|
|
391
|
+
reportPageCompileError(filename);
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
394
|
+
reportPageCompileSuccess(filename);
|
|
366
395
|
}
|
|
367
|
-
const { pageContent, pageMetadata, slug } = await createPage(filename, contentStr, CMD_EXEC_PATH, [], [], handleParseError);
|
|
368
|
-
await fse.outputFile(targetPath, pageContent, {
|
|
369
|
-
flag: 'w',
|
|
370
|
-
});
|
|
371
|
-
upsertPageMetadataCacheEntry(slug, pageMetadata);
|
|
372
396
|
break;
|
|
373
397
|
}
|
|
374
398
|
case 'snippet': {
|
|
@@ -2,9 +2,13 @@ export declare const markOnDemandPagesReady: () => void;
|
|
|
2
2
|
export type CompileEvent = {
|
|
3
3
|
path: string;
|
|
4
4
|
active: boolean;
|
|
5
|
+
error?: boolean;
|
|
5
6
|
};
|
|
6
7
|
type CompileListener = (event: CompileEvent) => void;
|
|
7
8
|
export declare const setCompileListener: (listener: CompileListener) => void;
|
|
9
|
+
export declare const getFailedCompileEvents: () => CompileEvent[];
|
|
10
|
+
export declare const reportPageCompileSuccess: (filename: string) => void;
|
|
11
|
+
export declare const reportPageCompileError: (filename: string) => void;
|
|
8
12
|
export declare const ensurePageCompiled: (pathname: string, options?: {
|
|
9
13
|
silent?: boolean;
|
|
10
14
|
}) => Promise<void>;
|
|
@@ -8,7 +8,7 @@ import { startDevTiming } from './dev-timing.js';
|
|
|
8
8
|
import { getImportedFilesFromCache } from './listener/importCache.js';
|
|
9
9
|
import { upsertPageMetadataCacheEntry } from './listener/page-metadata-cache.js';
|
|
10
10
|
import { resolvePageImports } from './listener/resolve-page-imports.js';
|
|
11
|
-
import { getMintIgnoreGlobs, handleParseError
|
|
11
|
+
import { getMintIgnoreGlobs, handleParseError } from './listener/utils.js';
|
|
12
12
|
const { readFile } = _promises;
|
|
13
13
|
let resolveReady = () => { };
|
|
14
14
|
const ready = new Promise((resolve) => {
|
|
@@ -27,11 +27,12 @@ const pagePathForFilename = (filename) => {
|
|
|
27
27
|
const trackCompile = async (filename, task) => {
|
|
28
28
|
const path = pagePathForFilename(filename);
|
|
29
29
|
compileListener?.({ path, active: true });
|
|
30
|
+
let failed = false;
|
|
30
31
|
try {
|
|
31
|
-
|
|
32
|
+
failed = await task();
|
|
32
33
|
}
|
|
33
34
|
finally {
|
|
34
|
-
compileListener?.({ path, active: false });
|
|
35
|
+
compileListener?.({ path, active: false, error: failed || undefined });
|
|
35
36
|
}
|
|
36
37
|
};
|
|
37
38
|
const inflight = new Map();
|
|
@@ -69,25 +70,50 @@ const candidateFilenames = (slug) => [
|
|
|
69
70
|
`${slug}/index.md`,
|
|
70
71
|
];
|
|
71
72
|
const failedCompiles = new Map();
|
|
73
|
+
export const getFailedCompileEvents = () => Array.from(failedCompiles.keys()).map((filename) => ({
|
|
74
|
+
path: pagePathForFilename(filename),
|
|
75
|
+
active: false,
|
|
76
|
+
error: true,
|
|
77
|
+
}));
|
|
78
|
+
export const reportPageCompileSuccess = (filename) => {
|
|
79
|
+
if (!failedCompiles.delete(filename))
|
|
80
|
+
return;
|
|
81
|
+
compileListener?.({ path: pagePathForFilename(filename), active: false });
|
|
82
|
+
};
|
|
83
|
+
export const reportPageCompileError = (filename) => {
|
|
84
|
+
failedCompiles.set(filename, 0);
|
|
85
|
+
compileListener?.({ path: pagePathForFilename(filename), active: false, error: true });
|
|
86
|
+
};
|
|
72
87
|
const compilePage = async (filename, sourcePath, targetPath, sourceMtimeMs) => {
|
|
73
88
|
const finish = startDevTiming(`compile ${filename}`);
|
|
89
|
+
let hasParseError = false;
|
|
90
|
+
const captureParseError = () => {
|
|
91
|
+
hasParseError = true;
|
|
92
|
+
};
|
|
74
93
|
try {
|
|
75
94
|
let contentStr = (await readFile(sourcePath)).toString();
|
|
76
|
-
const tree = await preparseMdxTree(contentStr, CMD_EXEC_PATH, sourcePath,
|
|
95
|
+
const tree = await preparseMdxTree(contentStr, CMD_EXEC_PATH, sourcePath, captureParseError);
|
|
77
96
|
const importsResponse = await findAndRemoveImports(tree);
|
|
78
97
|
if (hasImports(importsResponse)) {
|
|
79
98
|
contentStr = stringifyTree(await resolvePageImports({ ...importsResponse, filename }));
|
|
80
99
|
}
|
|
81
|
-
const { pageContent, pageMetadata, slug } = await createPage(filename, contentStr, CMD_EXEC_PATH, [], [],
|
|
100
|
+
const { pageContent, pageMetadata, slug } = await createPage(filename, contentStr, CMD_EXEC_PATH, [], [], captureParseError);
|
|
82
101
|
await fse.outputFile(targetPath, pageContent, { flag: 'w' });
|
|
83
102
|
upsertPageMetadataCacheEntry(slug, pageMetadata);
|
|
103
|
+
if (hasParseError) {
|
|
104
|
+
failedCompiles.set(filename, sourceMtimeMs);
|
|
105
|
+
finish('failed');
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
84
108
|
failedCompiles.delete(filename);
|
|
85
109
|
finish();
|
|
110
|
+
return false;
|
|
86
111
|
}
|
|
87
112
|
catch (error) {
|
|
88
113
|
failedCompiles.set(filename, sourceMtimeMs);
|
|
89
114
|
handleParseError(`Failed to compile ${filename}: ${error instanceof Error ? error.message : String(error)}`);
|
|
90
115
|
finish('failed');
|
|
116
|
+
return true;
|
|
91
117
|
}
|
|
92
118
|
};
|
|
93
119
|
export const ensurePageCompiled = async (pathname, options = {}) => {
|
|
@@ -106,6 +132,16 @@ export const ensurePageCompiled = async (pathname, options = {}) => {
|
|
|
106
132
|
const sourceStat = await fse.stat(sourcePath);
|
|
107
133
|
const targetPath = pathUtil.join(NEXT_PROPS_PATH, filename);
|
|
108
134
|
const targetStat = await fse.stat(targetPath).catch(() => undefined);
|
|
135
|
+
if (failedCompiles.get(filename) === sourceStat.mtimeMs) {
|
|
136
|
+
if (!options.silent) {
|
|
137
|
+
compileListener?.({
|
|
138
|
+
path: pagePathForFilename(filename),
|
|
139
|
+
active: false,
|
|
140
|
+
error: true,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
109
145
|
if (targetStat !== undefined && targetStat.mtimeMs >= sourceStat.mtimeMs) {
|
|
110
146
|
return;
|
|
111
147
|
}
|
|
@@ -113,14 +149,15 @@ export const ensurePageCompiled = async (pathname, options = {}) => {
|
|
|
113
149
|
if (getFileCategory(filename, { importedFiles: getImportedFilesFromCache() }) !== 'page') {
|
|
114
150
|
continue;
|
|
115
151
|
}
|
|
116
|
-
if (failedCompiles.get(filename) === sourceStat.mtimeMs) {
|
|
117
|
-
continue;
|
|
118
|
-
}
|
|
119
152
|
const pending = inflight.get(filename) ??
|
|
120
153
|
compilePage(filename, sourcePath, targetPath, sourceStat.mtimeMs).finally(() => {
|
|
121
154
|
inflight.delete(filename);
|
|
122
155
|
});
|
|
123
156
|
inflight.set(filename, pending);
|
|
124
|
-
|
|
157
|
+
if (options.silent) {
|
|
158
|
+
await pending;
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
return trackCompile(filename, () => pending);
|
|
125
162
|
}
|
|
126
163
|
};
|
|
@@ -11,7 +11,7 @@ import { addDevTimingLog, startDevTiming, timeDev } from './dev-timing.js';
|
|
|
11
11
|
import listener, { initializeDocsConfigHashCache, initializeFrontmatterHashCache, initializeImportCache, } from './listener/index.js';
|
|
12
12
|
import { refreshTrackedReferencedFiles } from './listener/referencedFiles.js';
|
|
13
13
|
import { getLocalNetworkIp } from './network.js';
|
|
14
|
-
import { ensurePageCompiled, markOnDemandPagesReady, setCompileListener } from './on-demand-page.js';
|
|
14
|
+
import { ensurePageCompiled, getFailedCompileEvents, markOnDemandPagesReady, setCompileListener, } from './on-demand-page.js';
|
|
15
15
|
import { setupNext } from './setupNext.js';
|
|
16
16
|
const PROXY_RESPONSE_HEADER_DENYLIST = new Set([
|
|
17
17
|
'connection',
|
|
@@ -135,6 +135,11 @@ export const run = async (argv) => {
|
|
|
135
135
|
setCompileListener((event) => {
|
|
136
136
|
io.emit('compiling', event);
|
|
137
137
|
});
|
|
138
|
+
io.on('connection', (socket) => {
|
|
139
|
+
for (const event of getFailedCompileEvents()) {
|
|
140
|
+
socket.emit('compiling', event);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
138
143
|
const finishServerListenTiming = startDevTiming('server ready');
|
|
139
144
|
server.listen(currentPort, () => {
|
|
140
145
|
finishServerListenTiming();
|