@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.
@@ -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 Worker !== "undefined" && typeof globalThis.window !== "undefined") {
95246
- log57.debug("Detected Web Worker support (browser/Electron environment)");
95247
- return "browser";
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, falling back to browser mode");
95256
- return "browser";
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
- log57.debug("Using browser mode as default");
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
- * 在浏览器/Electron 环境中,workerpool 会自动创建 Web Workers
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.info("\u{1F310} Initializing browser worker pool...");
95339
- const hasWorker = typeof Worker !== "undefined";
95340
- log57.debug("Browser environment details:", {
95341
- hasWorker,
95342
- hasWindow: typeof globalThis.window !== "undefined",
95343
- hasNavigator: typeof navigator !== "undefined",
95344
- hardwareConcurrency: typeof navigator !== "undefined" ? navigator.hardwareConcurrency : "N/A"
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 (handleWorkerTask function)");
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(handleWorkerTask, [task]);
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
- await processSSGParallel(projDir, modulesDir, markdown, onProgress, httpClient);
96269
- return getDomainInstances();
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
- var log61, WorkerState;
96377
- var init_worker_state = __esm({
96378
- "internal/application/worker/worker-state.ts"() {
96379
- "use strict";
96380
- init_log();
96381
- init_page_filter();
96382
- log61 = getDomainLogger("application", { component: "worker-state" });
96383
- WorkerState = class {
96384
- constructor(projDir, moduleDir) {
96385
- this.projDir = projDir;
96386
- this.moduleDir = moduleDir;
96387
- }
96388
- initialized = false;
96389
- /**
96390
- * 初始化 Worker 环境(只执行一次)
96391
- */
96392
- async initialize() {
96393
- if (this.initialized) {
96394
- log61.warn("Worker already initialized, skipping...");
96395
- return;
96396
- }
96397
- const startTime = performance.now();
96398
- log61.info("\u{1F680} Initializing worker environment...", {
96399
- projDir: this.projDir,
96400
- moduleDir: this.moduleDir
96401
- });
96402
- this.initialized = true;
96403
- const duration = performance.now() - startTime;
96404
- log61.info(`\u2705 Worker environment initialized in ${duration.toFixed(2)}ms`);
96405
- }
96406
- /**
96407
- * 处理一个批次的页面任务
96408
- * 运行完整的 SSG 流程,但通过过滤器只处理指定任务
96409
- *
96410
- * @param pageTasks - 包含语言和路径信息的任务列表
96411
- */
96412
- async processBatch(pageTasks) {
96413
- if (!this.initialized) {
96414
- throw new Error("Worker not initialized. Call initialize() first.");
96415
- }
96416
- const startTime = performance.now();
96417
- const errors2 = [];
96418
- log61.info(`\u{1F4E6} Processing batch: ${pageTasks.length} tasks`);
96419
- try {
96420
- setPageFilter(pageTasks);
96421
- log61.debug(`Filter set for ${pageTasks.length} tasks`);
96422
- const { generateStaticSite: generateStaticSite2 } = await Promise.resolve().then(() => (init_ssg(), ssg_exports));
96423
- await generateStaticSite2(this.projDir, this.moduleDir);
96424
- log61.debug("\u2705 Tasks processed (filtered)");
96425
- const duration = performance.now() - startTime;
96426
- const result = {
96427
- success: true,
96428
- processedCount: pageTasks.length,
96429
- totalCount: pageTasks.length,
96430
- duration,
96431
- errors: errors2
96432
- };
96433
- log61.info(`\u2705 Batch processed: ${pageTasks.length} tasks in ${duration.toFixed(2)}ms`);
96434
- return result;
96435
- } catch (error) {
96436
- const message = error instanceof Error ? error.message : String(error);
96437
- const errorMsg = `Batch processing failed: ${message}`;
96438
- log61.error(`\u274C ${errorMsg}`);
96439
- errors2.push(errorMsg);
96440
- const duration = performance.now() - startTime;
96441
- return {
96442
- success: false,
96443
- processedCount: 0,
96444
- totalCount: pageTasks.length,
96445
- duration,
96446
- errors: errors2
96447
- };
96448
- } finally {
96449
- clearPageFilter();
96450
- }
96451
- }
96452
- /**
96453
- * 清理资源
96454
- */
96455
- async cleanup() {
96456
- log61.info("\u{1F9F9} Cleaning up worker resources...");
96457
- this.initialized = false;
96458
- }
96459
- /**
96460
- * 获取统计信息
96461
- */
96462
- getStats() {
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.9",
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})}});})();