@mdfriday/foundry 26.2.9 → 26.2.11
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 +446 -96835
- package/dist/worker/worker-node.js +144 -144
- 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,38 @@ var init_pool_manager = __esm({
|
|
|
95242
95241
|
* 这样可以正确识别 Electron/Obsidian 环境(有 Node.js API 但只支持 Web Workers)
|
|
95243
95242
|
*/
|
|
95244
95243
|
detectEnvironment() {
|
|
95245
|
-
if (typeof
|
|
95246
|
-
log57.
|
|
95247
|
-
|
|
95244
|
+
if (typeof process !== "undefined" && process.type === "renderer") {
|
|
95245
|
+
log57.info("\u{1F310} Detected Electron Renderer Process (Obsidian plugin environment)");
|
|
95246
|
+
log57.info("\u26A0\uFE0F worker_threads NOT available in renderer process");
|
|
95247
|
+
log57.info("\u{1F4A1} Web Workers available but SSG requires Node.js fs access");
|
|
95248
|
+
log57.info("\u{1F4A1} System will fall back to serial processing");
|
|
95249
|
+
if (typeof Worker !== "undefined") {
|
|
95250
|
+
return "browser";
|
|
95251
|
+
}
|
|
95252
|
+
throw new Error("No worker support in renderer process");
|
|
95248
95253
|
}
|
|
95249
95254
|
if (typeof process !== "undefined" && process.versions && process.versions.node) {
|
|
95250
95255
|
try {
|
|
95251
95256
|
require.resolve("worker_threads");
|
|
95252
95257
|
log57.debug("Detected Node.js Worker Threads support");
|
|
95258
|
+
if (process.versions.electron) {
|
|
95259
|
+
log57.info("\u2728 Detected Electron Main Process - using Node.js Worker Threads");
|
|
95260
|
+
}
|
|
95253
95261
|
return "node";
|
|
95254
95262
|
} catch {
|
|
95255
|
-
log57.debug("Node.js detected but worker_threads unavailable
|
|
95256
|
-
|
|
95263
|
+
log57.debug("Node.js detected but worker_threads unavailable");
|
|
95264
|
+
if (typeof Worker !== "undefined" && typeof globalThis.window !== "undefined") {
|
|
95265
|
+
log57.warn("\u26A0\uFE0F Falling back to Web Workers (limited: no Node.js API access)");
|
|
95266
|
+
return "browser";
|
|
95267
|
+
}
|
|
95268
|
+
throw new Error("No worker support available (neither Worker Threads nor Web Workers)");
|
|
95257
95269
|
}
|
|
95258
95270
|
}
|
|
95259
|
-
|
|
95271
|
+
if (typeof Worker !== "undefined" && typeof globalThis.window !== "undefined") {
|
|
95272
|
+
log57.debug("Detected Web Worker support (pure browser environment)");
|
|
95273
|
+
return "browser";
|
|
95274
|
+
}
|
|
95275
|
+
log57.warn("Unable to detect environment reliably, defaulting to browser mode");
|
|
95260
95276
|
return "browser";
|
|
95261
95277
|
}
|
|
95262
95278
|
/**
|
|
@@ -95332,34 +95348,19 @@ var init_pool_manager = __esm({
|
|
|
95332
95348
|
/**
|
|
95333
95349
|
* 初始化浏览器 Worker 池
|
|
95334
95350
|
*
|
|
95335
|
-
*
|
|
95351
|
+
* ⚠️ 当前不支持纯浏览器环境的并行处理
|
|
95352
|
+
* 原因:SSG 依赖 Node.js 文件系统 API(fs、path 等),Web Workers 无法访问
|
|
95353
|
+
*
|
|
95354
|
+
* 注:Electron/Obsidian 应该使用 Node.js Worker Threads(在 detectEnvironment 中处理)
|
|
95336
95355
|
*/
|
|
95337
95356
|
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
|
-
}
|
|
95357
|
+
log57.error("\u274C Browser/Web Workers mode is not supported for SSG parallel processing");
|
|
95358
|
+
log57.info("\u{1F4A1} Reason: SSG requires Node.js file system access (fs, path, etc.)");
|
|
95359
|
+
log57.info("\u{1F4A1} Electron/Obsidian: Should use Node.js Worker Threads instead");
|
|
95360
|
+
log57.info("\u{1F4A1} Pure browser: Parallel processing not available, use serial mode");
|
|
95361
|
+
throw new Error(
|
|
95362
|
+
"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."
|
|
95363
|
+
);
|
|
95363
95364
|
}
|
|
95364
95365
|
/**
|
|
95365
95366
|
* 执行 Worker 任务
|
|
@@ -95382,15 +95383,14 @@ var init_pool_manager = __esm({
|
|
|
95382
95383
|
log57.debug("\u{1F4E5} Node worker response received", { success: response.success });
|
|
95383
95384
|
return response;
|
|
95384
95385
|
} else {
|
|
95385
|
-
log57.debug("\u{1F310} Using browser worker (
|
|
95386
|
-
log57.debug("handleWorkerTask type:", typeof handleWorkerTask);
|
|
95386
|
+
log57.debug("\u{1F310} Using browser worker (calling registered processTask)");
|
|
95387
95387
|
log57.debug("Task being sent to worker:", JSON.stringify({
|
|
95388
95388
|
type: task.type,
|
|
95389
95389
|
projDir: task.projDir,
|
|
95390
95390
|
moduleDir: task.moduleDir,
|
|
95391
95391
|
pageTasksCount: task.pageTasks?.length
|
|
95392
95392
|
}));
|
|
95393
|
-
const response = await this.pool.exec(
|
|
95393
|
+
const response = await this.pool.exec("processTask", [task]);
|
|
95394
95394
|
log57.debug("\u{1F4E5} Browser worker response received", {
|
|
95395
95395
|
success: response.success,
|
|
95396
95396
|
hasData: !!response.data,
|
|
@@ -96265,9 +96265,21 @@ async function serveSSG(projDir, modulesDir, markdown, onProgress, httpClient) {
|
|
|
96265
96265
|
process.chdir(projDir);
|
|
96266
96266
|
const tasks2 = await collectAllPageTasks(projDir, modulesDir, markdown, onProgress, httpClient);
|
|
96267
96267
|
if (tasks2.length > 80) {
|
|
96268
|
-
|
|
96269
|
-
|
|
96268
|
+
log60.info(`\u{1F4CA} Found ${tasks2.length} pages, attempting parallel processing...`);
|
|
96269
|
+
try {
|
|
96270
|
+
await processSSGParallel(projDir, modulesDir, markdown, onProgress, httpClient);
|
|
96271
|
+
return getDomainInstances();
|
|
96272
|
+
} catch (parallelError) {
|
|
96273
|
+
const errorMessage = parallelError instanceof Error ? parallelError.message : String(parallelError);
|
|
96274
|
+
if (errorMessage.includes("PARALLEL_NOT_SUPPORTED")) {
|
|
96275
|
+
log60.warn("\u26A0\uFE0F Parallel processing not available, falling back to serial processing");
|
|
96276
|
+
log60.info(`\u{1F504} Processing ${tasks2.length} pages in serial mode...`);
|
|
96277
|
+
return await generateStaticSiteWithProgress(projDir, modulesDir, markdown, onProgress, httpClient);
|
|
96278
|
+
}
|
|
96279
|
+
throw parallelError;
|
|
96280
|
+
}
|
|
96270
96281
|
}
|
|
96282
|
+
log60.info(`\u{1F4CA} Found ${tasks2.length} pages, using serial processing...`);
|
|
96271
96283
|
return await generateStaticSiteWithProgress(projDir, modulesDir, markdown, onProgress, httpClient);
|
|
96272
96284
|
} catch (error) {
|
|
96273
96285
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -96372,105 +96384,105 @@ var init_ssg = __esm({
|
|
|
96372
96384
|
}
|
|
96373
96385
|
});
|
|
96374
96386
|
|
|
96387
|
+
// internal/application/worker/worker-node.ts
|
|
96388
|
+
var workerpool2 = __toESM2(require("workerpool"));
|
|
96389
|
+
|
|
96375
96390
|
// 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
|
-
}
|
|
96391
|
+
init_log();
|
|
96392
|
+
init_page_filter();
|
|
96393
|
+
var log61 = getDomainLogger("application", { component: "worker-state" });
|
|
96394
|
+
var WorkerState = class {
|
|
96395
|
+
constructor(projDir, moduleDir) {
|
|
96396
|
+
this.projDir = projDir;
|
|
96397
|
+
this.moduleDir = moduleDir;
|
|
96398
|
+
}
|
|
96399
|
+
initialized = false;
|
|
96400
|
+
/**
|
|
96401
|
+
* 初始化 Worker 环境(只执行一次)
|
|
96402
|
+
*/
|
|
96403
|
+
async initialize() {
|
|
96404
|
+
if (this.initialized) {
|
|
96405
|
+
log61.warn("Worker already initialized, skipping...");
|
|
96406
|
+
return;
|
|
96407
|
+
}
|
|
96408
|
+
const startTime = performance.now();
|
|
96409
|
+
log61.info("\u{1F680} Initializing worker environment...", {
|
|
96410
|
+
projDir: this.projDir,
|
|
96411
|
+
moduleDir: this.moduleDir
|
|
96412
|
+
});
|
|
96413
|
+
this.initialized = true;
|
|
96414
|
+
const duration = performance.now() - startTime;
|
|
96415
|
+
log61.info(`\u2705 Worker environment initialized in ${duration.toFixed(2)}ms`);
|
|
96416
|
+
}
|
|
96417
|
+
/**
|
|
96418
|
+
* 处理一个批次的页面任务
|
|
96419
|
+
* 运行完整的 SSG 流程,但通过过滤器只处理指定任务
|
|
96420
|
+
*
|
|
96421
|
+
* @param pageTasks - 包含语言和路径信息的任务列表
|
|
96422
|
+
*/
|
|
96423
|
+
async processBatch(pageTasks) {
|
|
96424
|
+
if (!this.initialized) {
|
|
96425
|
+
throw new Error("Worker not initialized. Call initialize() first.");
|
|
96426
|
+
}
|
|
96427
|
+
const startTime = performance.now();
|
|
96428
|
+
const errors2 = [];
|
|
96429
|
+
log61.info(`\u{1F4E6} Processing batch: ${pageTasks.length} tasks`);
|
|
96430
|
+
try {
|
|
96431
|
+
setPageFilter(pageTasks);
|
|
96432
|
+
log61.debug(`Filter set for ${pageTasks.length} tasks`);
|
|
96433
|
+
const { generateStaticSite: generateStaticSite2 } = await Promise.resolve().then(() => (init_ssg(), ssg_exports));
|
|
96434
|
+
await generateStaticSite2(this.projDir, this.moduleDir);
|
|
96435
|
+
log61.debug("\u2705 Tasks processed (filtered)");
|
|
96436
|
+
const duration = performance.now() - startTime;
|
|
96437
|
+
const result = {
|
|
96438
|
+
success: true,
|
|
96439
|
+
processedCount: pageTasks.length,
|
|
96440
|
+
totalCount: pageTasks.length,
|
|
96441
|
+
duration,
|
|
96442
|
+
errors: errors2
|
|
96443
|
+
};
|
|
96444
|
+
log61.info(`\u2705 Batch processed: ${pageTasks.length} tasks in ${duration.toFixed(2)}ms`);
|
|
96445
|
+
return result;
|
|
96446
|
+
} catch (error) {
|
|
96447
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
96448
|
+
const errorMsg = `Batch processing failed: ${message}`;
|
|
96449
|
+
log61.error(`\u274C ${errorMsg}`);
|
|
96450
|
+
errors2.push(errorMsg);
|
|
96451
|
+
const duration = performance.now() - startTime;
|
|
96452
|
+
return {
|
|
96453
|
+
success: false,
|
|
96454
|
+
processedCount: 0,
|
|
96455
|
+
totalCount: pageTasks.length,
|
|
96456
|
+
duration,
|
|
96457
|
+
errors: errors2
|
|
96458
|
+
};
|
|
96459
|
+
} finally {
|
|
96460
|
+
clearPageFilter();
|
|
96461
|
+
}
|
|
96462
|
+
}
|
|
96463
|
+
/**
|
|
96464
|
+
* 清理资源
|
|
96465
|
+
*/
|
|
96466
|
+
async cleanup() {
|
|
96467
|
+
log61.info("\u{1F9F9} Cleaning up worker resources...");
|
|
96468
|
+
this.initialized = false;
|
|
96469
|
+
}
|
|
96470
|
+
/**
|
|
96471
|
+
* 获取统计信息
|
|
96472
|
+
*/
|
|
96473
|
+
getStats() {
|
|
96474
|
+
return {
|
|
96475
|
+
initialized: this.initialized,
|
|
96476
|
+
projDir: this.projDir,
|
|
96477
|
+
moduleDir: this.moduleDir
|
|
96469
96478
|
};
|
|
96470
96479
|
}
|
|
96471
|
-
}
|
|
96480
|
+
};
|
|
96472
96481
|
|
|
96473
96482
|
// internal/application/worker/worker-main.ts
|
|
96483
|
+
init_log();
|
|
96484
|
+
var log62 = getDomainLogger("application", { component: "worker-main" });
|
|
96485
|
+
var workerState = null;
|
|
96474
96486
|
async function handleWorkerTask(task) {
|
|
96475
96487
|
log62.info(`\u{1F528} handleWorkerTask called with task type: ${task.type}`);
|
|
96476
96488
|
log62.debug("Task details:", {
|
|
@@ -96601,20 +96613,8 @@ async function handleCleanup() {
|
|
|
96601
96613
|
data: { message: "Worker cleaned up successfully" }
|
|
96602
96614
|
};
|
|
96603
96615
|
}
|
|
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
96616
|
|
|
96615
96617
|
// internal/application/worker/worker-node.ts
|
|
96616
|
-
var workerpool2 = __toESM2(require("workerpool"));
|
|
96617
|
-
init_worker_main();
|
|
96618
96618
|
async function processTask(task) {
|
|
96619
96619
|
return await handleWorkerTask(task);
|
|
96620
96620
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mdfriday/foundry",
|
|
3
|
-
"version": "26.2.
|
|
3
|
+
"version": "26.2.11",
|
|
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})}});})();
|