@mdfriday/foundry 26.2.9 → 26.2.10
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/dist/index.js +1 -1
- package/dist/worker/pool-manager.js +438 -96837
- package/dist/worker/worker-node.js +135 -145
- package/package.json +1 -1
- package/dist/worker/worker-inline.js +0 -1
|
@@ -95220,7 +95220,6 @@ var init_pool_manager = __esm({
|
|
|
95220
95220
|
"use strict";
|
|
95221
95221
|
init_log();
|
|
95222
95222
|
workerpool = __toESM2(require("workerpool"));
|
|
95223
|
-
init_worker_main();
|
|
95224
95223
|
os = __toESM2(require("os"));
|
|
95225
95224
|
log57 = getDomainLogger("application", { component: "pool-manager" });
|
|
95226
95225
|
WorkerPoolManager = class {
|
|
@@ -95242,21 +95241,28 @@ var init_pool_manager = __esm({
|
|
|
95242
95241
|
* 这样可以正确识别 Electron/Obsidian 环境(有 Node.js API 但只支持 Web Workers)
|
|
95243
95242
|
*/
|
|
95244
95243
|
detectEnvironment() {
|
|
95245
|
-
if (typeof Worker !== "undefined" && typeof globalThis.window !== "undefined") {
|
|
95246
|
-
log57.debug("Detected Web Worker support (browser/Electron environment)");
|
|
95247
|
-
return "browser";
|
|
95248
|
-
}
|
|
95249
95244
|
if (typeof process !== "undefined" && process.versions && process.versions.node) {
|
|
95250
95245
|
try {
|
|
95251
95246
|
require.resolve("worker_threads");
|
|
95252
95247
|
log57.debug("Detected Node.js Worker Threads support");
|
|
95248
|
+
if (process.versions.electron) {
|
|
95249
|
+
log57.info("\u2728 Detected Electron environment - using Node.js Worker Threads (full Node.js API support)");
|
|
95250
|
+
}
|
|
95253
95251
|
return "node";
|
|
95254
95252
|
} catch {
|
|
95255
|
-
log57.debug("Node.js detected but worker_threads unavailable
|
|
95256
|
-
|
|
95253
|
+
log57.debug("Node.js detected but worker_threads unavailable");
|
|
95254
|
+
if (typeof Worker !== "undefined" && typeof globalThis.window !== "undefined") {
|
|
95255
|
+
log57.warn("\u26A0\uFE0F Falling back to Web Workers (limited: no Node.js API access)");
|
|
95256
|
+
return "browser";
|
|
95257
|
+
}
|
|
95258
|
+
throw new Error("No worker support available (neither Worker Threads nor Web Workers)");
|
|
95257
95259
|
}
|
|
95258
95260
|
}
|
|
95259
|
-
|
|
95261
|
+
if (typeof Worker !== "undefined" && typeof globalThis.window !== "undefined") {
|
|
95262
|
+
log57.debug("Detected Web Worker support (pure browser environment)");
|
|
95263
|
+
return "browser";
|
|
95264
|
+
}
|
|
95265
|
+
log57.warn("Unable to detect environment reliably, defaulting to browser mode");
|
|
95260
95266
|
return "browser";
|
|
95261
95267
|
}
|
|
95262
95268
|
/**
|
|
@@ -95332,34 +95338,19 @@ var init_pool_manager = __esm({
|
|
|
95332
95338
|
/**
|
|
95333
95339
|
* 初始化浏览器 Worker 池
|
|
95334
95340
|
*
|
|
95335
|
-
*
|
|
95341
|
+
* ⚠️ 当前不支持纯浏览器环境的并行处理
|
|
95342
|
+
* 原因:SSG 依赖 Node.js 文件系统 API(fs、path 等),Web Workers 无法访问
|
|
95343
|
+
*
|
|
95344
|
+
* 注:Electron/Obsidian 应该使用 Node.js Worker Threads(在 detectEnvironment 中处理)
|
|
95336
95345
|
*/
|
|
95337
95346
|
async initializeBrowserPool() {
|
|
95338
|
-
log57.
|
|
95339
|
-
|
|
95340
|
-
log57.
|
|
95341
|
-
|
|
95342
|
-
|
|
95343
|
-
|
|
95344
|
-
|
|
95345
|
-
});
|
|
95346
|
-
try {
|
|
95347
|
-
this.pool = workerpool.pool({
|
|
95348
|
-
minWorkers: this.workerCount,
|
|
95349
|
-
maxWorkers: this.workerCount,
|
|
95350
|
-
workerType: "web"
|
|
95351
|
-
});
|
|
95352
|
-
log57.info(`\u2705 Browser worker pool created with ${this.workerCount} workers`);
|
|
95353
|
-
log57.debug("Pool configuration:", {
|
|
95354
|
-
minWorkers: this.workerCount,
|
|
95355
|
-
maxWorkers: this.workerCount,
|
|
95356
|
-
workerType: "web"
|
|
95357
|
-
});
|
|
95358
|
-
} catch (error) {
|
|
95359
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
95360
|
-
log57.error(`Failed to create browser worker pool: ${message}`);
|
|
95361
|
-
throw error;
|
|
95362
|
-
}
|
|
95347
|
+
log57.error("\u274C Browser/Web Workers mode is not supported for SSG parallel processing");
|
|
95348
|
+
log57.info("\u{1F4A1} Reason: SSG requires Node.js file system access (fs, path, etc.)");
|
|
95349
|
+
log57.info("\u{1F4A1} Electron/Obsidian: Should use Node.js Worker Threads instead");
|
|
95350
|
+
log57.info("\u{1F4A1} Pure browser: Parallel processing not available, use serial mode");
|
|
95351
|
+
throw new Error(
|
|
95352
|
+
"PARALLEL_NOT_SUPPORTED: SSG parallel processing requires Node.js file system access. Web Workers cannot access fs/path modules. System will fall back to serial processing."
|
|
95353
|
+
);
|
|
95363
95354
|
}
|
|
95364
95355
|
/**
|
|
95365
95356
|
* 执行 Worker 任务
|
|
@@ -95382,15 +95373,14 @@ var init_pool_manager = __esm({
|
|
|
95382
95373
|
log57.debug("\u{1F4E5} Node worker response received", { success: response.success });
|
|
95383
95374
|
return response;
|
|
95384
95375
|
} else {
|
|
95385
|
-
log57.debug("\u{1F310} Using browser worker (
|
|
95386
|
-
log57.debug("handleWorkerTask type:", typeof handleWorkerTask);
|
|
95376
|
+
log57.debug("\u{1F310} Using browser worker (calling registered processTask)");
|
|
95387
95377
|
log57.debug("Task being sent to worker:", JSON.stringify({
|
|
95388
95378
|
type: task.type,
|
|
95389
95379
|
projDir: task.projDir,
|
|
95390
95380
|
moduleDir: task.moduleDir,
|
|
95391
95381
|
pageTasksCount: task.pageTasks?.length
|
|
95392
95382
|
}));
|
|
95393
|
-
const response = await this.pool.exec(
|
|
95383
|
+
const response = await this.pool.exec("processTask", [task]);
|
|
95394
95384
|
log57.debug("\u{1F4E5} Browser worker response received", {
|
|
95395
95385
|
success: response.success,
|
|
95396
95386
|
hasData: !!response.data,
|
|
@@ -96265,9 +96255,21 @@ async function serveSSG(projDir, modulesDir, markdown, onProgress, httpClient) {
|
|
|
96265
96255
|
process.chdir(projDir);
|
|
96266
96256
|
const tasks2 = await collectAllPageTasks(projDir, modulesDir, markdown, onProgress, httpClient);
|
|
96267
96257
|
if (tasks2.length > 80) {
|
|
96268
|
-
|
|
96269
|
-
|
|
96258
|
+
log60.info(`\u{1F4CA} Found ${tasks2.length} pages, attempting parallel processing...`);
|
|
96259
|
+
try {
|
|
96260
|
+
await processSSGParallel(projDir, modulesDir, markdown, onProgress, httpClient);
|
|
96261
|
+
return getDomainInstances();
|
|
96262
|
+
} catch (parallelError) {
|
|
96263
|
+
const errorMessage = parallelError instanceof Error ? parallelError.message : String(parallelError);
|
|
96264
|
+
if (errorMessage.includes("PARALLEL_NOT_SUPPORTED")) {
|
|
96265
|
+
log60.warn("\u26A0\uFE0F Parallel processing not available, falling back to serial processing");
|
|
96266
|
+
log60.info(`\u{1F504} Processing ${tasks2.length} pages in serial mode...`);
|
|
96267
|
+
return await generateStaticSiteWithProgress(projDir, modulesDir, markdown, onProgress, httpClient);
|
|
96268
|
+
}
|
|
96269
|
+
throw parallelError;
|
|
96270
|
+
}
|
|
96270
96271
|
}
|
|
96272
|
+
log60.info(`\u{1F4CA} Found ${tasks2.length} pages, using serial processing...`);
|
|
96271
96273
|
return await generateStaticSiteWithProgress(projDir, modulesDir, markdown, onProgress, httpClient);
|
|
96272
96274
|
} catch (error) {
|
|
96273
96275
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -96372,105 +96374,105 @@ var init_ssg = __esm({
|
|
|
96372
96374
|
}
|
|
96373
96375
|
});
|
|
96374
96376
|
|
|
96377
|
+
// internal/application/worker/worker-node.ts
|
|
96378
|
+
var workerpool2 = __toESM2(require("workerpool"));
|
|
96379
|
+
|
|
96375
96380
|
// internal/application/worker/worker-state.ts
|
|
96376
|
-
|
|
96377
|
-
|
|
96378
|
-
|
|
96379
|
-
|
|
96380
|
-
|
|
96381
|
-
|
|
96382
|
-
|
|
96383
|
-
|
|
96384
|
-
|
|
96385
|
-
|
|
96386
|
-
|
|
96387
|
-
|
|
96388
|
-
|
|
96389
|
-
|
|
96390
|
-
|
|
96391
|
-
|
|
96392
|
-
|
|
96393
|
-
|
|
96394
|
-
|
|
96395
|
-
|
|
96396
|
-
|
|
96397
|
-
|
|
96398
|
-
|
|
96399
|
-
|
|
96400
|
-
|
|
96401
|
-
|
|
96402
|
-
|
|
96403
|
-
|
|
96404
|
-
|
|
96405
|
-
|
|
96406
|
-
|
|
96407
|
-
|
|
96408
|
-
|
|
96409
|
-
|
|
96410
|
-
|
|
96411
|
-
|
|
96412
|
-
|
|
96413
|
-
|
|
96414
|
-
|
|
96415
|
-
|
|
96416
|
-
|
|
96417
|
-
|
|
96418
|
-
|
|
96419
|
-
|
|
96420
|
-
|
|
96421
|
-
|
|
96422
|
-
|
|
96423
|
-
|
|
96424
|
-
|
|
96425
|
-
|
|
96426
|
-
|
|
96427
|
-
|
|
96428
|
-
|
|
96429
|
-
|
|
96430
|
-
|
|
96431
|
-
|
|
96432
|
-
|
|
96433
|
-
|
|
96434
|
-
|
|
96435
|
-
|
|
96436
|
-
|
|
96437
|
-
|
|
96438
|
-
|
|
96439
|
-
|
|
96440
|
-
|
|
96441
|
-
|
|
96442
|
-
|
|
96443
|
-
|
|
96444
|
-
|
|
96445
|
-
|
|
96446
|
-
|
|
96447
|
-
|
|
96448
|
-
|
|
96449
|
-
|
|
96450
|
-
|
|
96451
|
-
|
|
96452
|
-
|
|
96453
|
-
|
|
96454
|
-
|
|
96455
|
-
|
|
96456
|
-
|
|
96457
|
-
|
|
96458
|
-
|
|
96459
|
-
|
|
96460
|
-
|
|
96461
|
-
|
|
96462
|
-
|
|
96463
|
-
return {
|
|
96464
|
-
initialized: this.initialized,
|
|
96465
|
-
projDir: this.projDir,
|
|
96466
|
-
moduleDir: this.moduleDir
|
|
96467
|
-
};
|
|
96468
|
-
}
|
|
96381
|
+
init_log();
|
|
96382
|
+
init_page_filter();
|
|
96383
|
+
var log61 = getDomainLogger("application", { component: "worker-state" });
|
|
96384
|
+
var WorkerState = class {
|
|
96385
|
+
constructor(projDir, moduleDir) {
|
|
96386
|
+
this.projDir = projDir;
|
|
96387
|
+
this.moduleDir = moduleDir;
|
|
96388
|
+
}
|
|
96389
|
+
initialized = false;
|
|
96390
|
+
/**
|
|
96391
|
+
* 初始化 Worker 环境(只执行一次)
|
|
96392
|
+
*/
|
|
96393
|
+
async initialize() {
|
|
96394
|
+
if (this.initialized) {
|
|
96395
|
+
log61.warn("Worker already initialized, skipping...");
|
|
96396
|
+
return;
|
|
96397
|
+
}
|
|
96398
|
+
const startTime = performance.now();
|
|
96399
|
+
log61.info("\u{1F680} Initializing worker environment...", {
|
|
96400
|
+
projDir: this.projDir,
|
|
96401
|
+
moduleDir: this.moduleDir
|
|
96402
|
+
});
|
|
96403
|
+
this.initialized = true;
|
|
96404
|
+
const duration = performance.now() - startTime;
|
|
96405
|
+
log61.info(`\u2705 Worker environment initialized in ${duration.toFixed(2)}ms`);
|
|
96406
|
+
}
|
|
96407
|
+
/**
|
|
96408
|
+
* 处理一个批次的页面任务
|
|
96409
|
+
* 运行完整的 SSG 流程,但通过过滤器只处理指定任务
|
|
96410
|
+
*
|
|
96411
|
+
* @param pageTasks - 包含语言和路径信息的任务列表
|
|
96412
|
+
*/
|
|
96413
|
+
async processBatch(pageTasks) {
|
|
96414
|
+
if (!this.initialized) {
|
|
96415
|
+
throw new Error("Worker not initialized. Call initialize() first.");
|
|
96416
|
+
}
|
|
96417
|
+
const startTime = performance.now();
|
|
96418
|
+
const errors2 = [];
|
|
96419
|
+
log61.info(`\u{1F4E6} Processing batch: ${pageTasks.length} tasks`);
|
|
96420
|
+
try {
|
|
96421
|
+
setPageFilter(pageTasks);
|
|
96422
|
+
log61.debug(`Filter set for ${pageTasks.length} tasks`);
|
|
96423
|
+
const { generateStaticSite: generateStaticSite2 } = await Promise.resolve().then(() => (init_ssg(), ssg_exports));
|
|
96424
|
+
await generateStaticSite2(this.projDir, this.moduleDir);
|
|
96425
|
+
log61.debug("\u2705 Tasks processed (filtered)");
|
|
96426
|
+
const duration = performance.now() - startTime;
|
|
96427
|
+
const result = {
|
|
96428
|
+
success: true,
|
|
96429
|
+
processedCount: pageTasks.length,
|
|
96430
|
+
totalCount: pageTasks.length,
|
|
96431
|
+
duration,
|
|
96432
|
+
errors: errors2
|
|
96433
|
+
};
|
|
96434
|
+
log61.info(`\u2705 Batch processed: ${pageTasks.length} tasks in ${duration.toFixed(2)}ms`);
|
|
96435
|
+
return result;
|
|
96436
|
+
} catch (error) {
|
|
96437
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
96438
|
+
const errorMsg = `Batch processing failed: ${message}`;
|
|
96439
|
+
log61.error(`\u274C ${errorMsg}`);
|
|
96440
|
+
errors2.push(errorMsg);
|
|
96441
|
+
const duration = performance.now() - startTime;
|
|
96442
|
+
return {
|
|
96443
|
+
success: false,
|
|
96444
|
+
processedCount: 0,
|
|
96445
|
+
totalCount: pageTasks.length,
|
|
96446
|
+
duration,
|
|
96447
|
+
errors: errors2
|
|
96448
|
+
};
|
|
96449
|
+
} finally {
|
|
96450
|
+
clearPageFilter();
|
|
96451
|
+
}
|
|
96452
|
+
}
|
|
96453
|
+
/**
|
|
96454
|
+
* 清理资源
|
|
96455
|
+
*/
|
|
96456
|
+
async cleanup() {
|
|
96457
|
+
log61.info("\u{1F9F9} Cleaning up worker resources...");
|
|
96458
|
+
this.initialized = false;
|
|
96459
|
+
}
|
|
96460
|
+
/**
|
|
96461
|
+
* 获取统计信息
|
|
96462
|
+
*/
|
|
96463
|
+
getStats() {
|
|
96464
|
+
return {
|
|
96465
|
+
initialized: this.initialized,
|
|
96466
|
+
projDir: this.projDir,
|
|
96467
|
+
moduleDir: this.moduleDir
|
|
96469
96468
|
};
|
|
96470
96469
|
}
|
|
96471
|
-
}
|
|
96470
|
+
};
|
|
96472
96471
|
|
|
96473
96472
|
// internal/application/worker/worker-main.ts
|
|
96473
|
+
init_log();
|
|
96474
|
+
var log62 = getDomainLogger("application", { component: "worker-main" });
|
|
96475
|
+
var workerState = null;
|
|
96474
96476
|
async function handleWorkerTask(task) {
|
|
96475
96477
|
log62.info(`\u{1F528} handleWorkerTask called with task type: ${task.type}`);
|
|
96476
96478
|
log62.debug("Task details:", {
|
|
@@ -96601,20 +96603,8 @@ async function handleCleanup() {
|
|
|
96601
96603
|
data: { message: "Worker cleaned up successfully" }
|
|
96602
96604
|
};
|
|
96603
96605
|
}
|
|
96604
|
-
var log62, workerState;
|
|
96605
|
-
var init_worker_main = __esm({
|
|
96606
|
-
"internal/application/worker/worker-main.ts"() {
|
|
96607
|
-
"use strict";
|
|
96608
|
-
init_worker_state();
|
|
96609
|
-
init_log();
|
|
96610
|
-
log62 = getDomainLogger("application", { component: "worker-main" });
|
|
96611
|
-
workerState = null;
|
|
96612
|
-
}
|
|
96613
|
-
});
|
|
96614
96606
|
|
|
96615
96607
|
// internal/application/worker/worker-node.ts
|
|
96616
|
-
var workerpool2 = __toESM2(require("workerpool"));
|
|
96617
|
-
init_worker_main();
|
|
96618
96608
|
async function processTask(task) {
|
|
96619
96609
|
return await handleWorkerTask(task);
|
|
96620
96610
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mdfriday/foundry",
|
|
3
|
-
"version": "26.2.
|
|
3
|
+
"version": "26.2.10",
|
|
4
4
|
"description": "The core engine of MDFriday. Convert Markdown and shortcodes into fully themed static sites – Hugo-style, powered by TypeScript.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";(()=>{if(typeof self.importScripts=="function")try{self.importScripts("workerpool")}catch(e){console.error("Failed to import workerpool:",e)}self.addEventListener("message",async e=>{let o=e.data;try{self.postMessage({success:!1,error:"Browser worker needs special initialization. Use workerpool.pool() with proper options."})}catch(s){let r=s instanceof Error?s.message:String(s);self.postMessage({success:!1,error:r})}});})();
|