UNPKG

@mdfriday/foundry

Version:

The core engine of MDFriday. Convert Markdown and shortcodes into fully themed static sites – Hugo-style, powered by TypeScript.

189 lines 6.85 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.IncrementalBuildCoordinator = void 0; const ssg_1 = require("./ssg"); const log_1 = require("../../pkg/log"); const content_file_watcher_1 = require("../../pkg/web/watcher/content-file-watcher"); const server_1 = require("../../pkg/web/server"); const log = (0, log_1.getDomainLogger)('build', { component: 'incremental-coordinator' }); class IncrementalBuildCoordinator { constructor(config) { this.config = config; this.buildInProgress = false; this.initialized = false; // 初始化文件监控器 if (config.enableWatching) { const watcherConfig = { contentDir: config.contentDir, projContentDir: config.projContentDir || config.contentDir, // 默认与 contentDir 相同 batchDelay: config.batchDelay || 500 }; this.fileWatcher = new content_file_watcher_1.ContentFileWatcher(watcherConfig); this.fileWatcher.onFileChange((events) => this.handleFileChanges(events)); } // 初始化 Live Reload 服务器 if (config.liveReload?.enabled !== false) { const liveReloadConfig = { port: config.liveReload?.port || 8091, host: config.liveReload?.host || 'localhost', livereloadPort: config.liveReload?.livereloadPort || 35729, publicDir: config.publicDir, enableLiveReload: true }; this.liveReloadServer = (0, server_1.createLiveReloadServer)(liveReloadConfig); } } /** * 初始化:执行首次完整构建并保存 domain 实例 */ async initialize() { if (this.initialized) { log.warn('IncrementalBuildCoordinator already initialized'); return; } await this.performFullBuildAndCacheDomains(); this.initialized = true; } /** * 执行完整构建并缓存 domain 实例 */ async performFullBuildAndCacheDomains() { try { this.domainInstances = await (0, ssg_1.serveSSG)(this.config.projDir, this.config.modulesDir, this.config.markdown, this.config.progressCallback); } catch (error) { log.error('Failed to perform full build and cache domains:', error); throw error; } } async startWatching() { if (!this.initialized) { throw new Error('Must call initialize() before startWatching()'); } // 启动文件监控 if (this.config.enableWatching && this.fileWatcher) { await this.fileWatcher.startWatching(); } // 启动 Live Reload 服务器 if (this.liveReloadServer) { await this.liveReloadServer.start(); } } async stopWatching() { // 停止文件监控 if (this.fileWatcher) { await this.fileWatcher.stopWatching(); } // 停止 Live Reload 服务器 if (this.liveReloadServer) { await this.liveReloadServer.stop(); } } /** * 处理文件变更事件,触发增量构建 * 阶段3-5:完整的增量构建流程 */ async handleFileChanges(events) { if (this.buildInProgress) { setTimeout(() => this.handleFileChanges(events), 1000); return; } try { this.buildInProgress = true; if (this.needFullRebuild(events)) { await this.performFullRebuild(events); return; } // 执行完整的增量构建流程 await this.performIncrementalBuild(events); } finally { this.buildInProgress = false; } } needFullRebuild(events) { return events.some(event => event.eventType === 'deleted' || event.eventType === 'created'); } /** * 执行增量构建(阶段3-5的核心实现) */ async performIncrementalBuild(events) { if (!this.domainInstances) { log.error('Domain instances not available, falling back to full rebuild'); await this.performFullRebuild(events); return; } try { // 阶段3: 从 FS Domain 获取修改文件的 FileMetaInfo const fileMetaInfos = await this.domainInstances.fs.getFileMetaInfos(this.getEventsFilePaths(events)); // 阶段4: 更新 Content Domain 的 PageMap 并标记 stale 页面 await this.domainInstances.content.handleChangeFiles(fileMetaInfos); // 阶段5: 在 Site Domain 中执行增量渲染 await this.domainInstances.site.render(); // 通知 Live Reload 客户端刷新 if (this.liveReloadServer) { const changedPaths = events.map(e => e.filePath); this.liveReloadServer.notifyReload(changedPaths); } } catch (error) { log.error('Incremental build failed, falling back to full rebuild:', error); await this.performFullRebuild(events); } } getEventsFilePaths(events) { return events.map(event => event.filePath); } /** * 第2阶段的临时实现:执行完整重建并通知 Live Reload */ async performFullRebuild(events) { await (0, ssg_1.processSSGWithProgress)(this.config.projDir, this.config.modulesDir, this.config.markdown, (progress) => { log.info(`Rebuild progress: ${progress.stage} - ${progress.percentage}%`); }); // 通知 Live Reload 客户端刷新 if (this.liveReloadServer) { const changedPaths = events.map(e => e.filePath); this.liveReloadServer.notifyReload(changedPaths); } } /** * 获取当前是否已初始化 */ isInitialized() { return this.initialized; } /** * 获取是否正在构建 */ isBuildInProgress() { return this.buildInProgress; } /** * 获取配置信息 */ getConfig() { return { ...this.config }; } getServerUrl() { if (this.liveReloadServer) { return this.liveReloadServer.getUrl(); } return ''; } /** * 获取 Live Reload 服务器状态 */ getLiveReloadStatus() { if (!this.liveReloadServer) { return { running: false }; } const isRunning = this.liveReloadServer.isServerRunning(); return { running: isRunning, ...(isRunning && { url: this.liveReloadServer.getUrl() }) }; } } exports.IncrementalBuildCoordinator = IncrementalBuildCoordinator; //# sourceMappingURL=incremental-build-coordinator.js.map