- VERSION file as authoritative version source - export.mjs reads VERSION with package.json fallback - bw-ota.ps1 DryRun mode for safe testing - auto-setup.ps1 bumped to v3.2.0 (Phase 8 OTA)
92 lines
2.8 KiB
JavaScript
92 lines
2.8 KiB
JavaScript
'use strict';
|
||
/**
|
||
* fast-cache.js — 启动期热数据快路径缓存 (P1-FAST-CACHE-V1)
|
||
*
|
||
* 通过 mtime 签名: 所有源文件未变 → 直接返回上次缓存。
|
||
* 仅缓存只读字段子集,避免缓存整个大 JSON 文件。
|
||
*
|
||
* 借鉴: OpenClaw entry.version-fast-path.ts (零模块加载快退出)
|
||
*
|
||
* Usage:
|
||
* const { readFastCache } = require('./lib/fast-cache.js');
|
||
* const cache = readFastCache() || {};
|
||
* const skillCount = cache.skillCount || 0;
|
||
*/
|
||
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
|
||
const ROOT = path.join(__dirname, '..', '..');
|
||
const CACHE_FILE = path.join(ROOT, 'debug', '.hook-fast-cache.json');
|
||
|
||
const SOURCES = [
|
||
{ file: path.join(ROOT, 'stats-compiled.json'), fields: ['summary', 'version'] },
|
||
// settings.json 不再读取 mcpServers (MCP 配置在 ~/.claude.json,由 stats 编译)
|
||
];
|
||
|
||
function readFastCache() {
|
||
try {
|
||
const mtimes = SOURCES.map(function(s) {
|
||
try { return fs.statSync(s.file).mtimeMs; } catch (_) { return 0; }
|
||
});
|
||
const sig = mtimes.join(':');
|
||
|
||
if (fs.existsSync(CACHE_FILE)) {
|
||
try {
|
||
const cache = JSON.parse(fs.readFileSync(CACHE_FILE, 'utf8'));
|
||
if (cache && cache._sig === sig) return cache;
|
||
} catch (_) { /* malformed cache, rebuild */ }
|
||
}
|
||
|
||
const rebuilt = { _sig: sig, _builtAt: Date.now() };
|
||
for (let i = 0; i < SOURCES.length; i++) {
|
||
const { file, fields } = SOURCES[i];
|
||
try {
|
||
const data = JSON.parse(fs.readFileSync(file, 'utf8'));
|
||
for (let j = 0; j < fields.length; j++) {
|
||
rebuilt[fields[j]] = data[fields[j]];
|
||
}
|
||
} catch (_) { /* missing file ok */ }
|
||
}
|
||
// P1-FAST-CACHE-V1-FIELDS-FIX: stats.summary 字段名修正
|
||
const _sum = rebuilt.summary || {};
|
||
rebuilt.skillCount = _sum.skills || 0;
|
||
rebuilt.hookCount = _sum.hooks || 0; // 总数
|
||
rebuilt.hookRegisteredCount = _sum.hooksRegistered || 0;
|
||
rebuilt.agentCount = _sum.agents || 0;
|
||
rebuilt.mcpCount = _sum.mcpTotal || _sum.mcp || 0;
|
||
|
||
// 异步写回 (不阻塞主流程)
|
||
setImmediate(function() {
|
||
try {
|
||
const cacheDir = path.dirname(CACHE_FILE);
|
||
if (!fs.existsSync(cacheDir)) fs.mkdirSync(cacheDir, { recursive: true });
|
||
const tmp = CACHE_FILE + '.tmp.' + process.pid;
|
||
fs.writeFileSync(tmp, JSON.stringify(rebuilt));
|
||
fs.renameSync(tmp, CACHE_FILE);
|
||
} catch (_) { /* best effort */ }
|
||
});
|
||
|
||
return rebuilt;
|
||
} catch (_) {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
function enableCompileCacheBestEffort() {
|
||
try {
|
||
const mod = require('node:module');
|
||
if (mod.enableCompileCache && !process.env.NODE_DISABLE_COMPILE_CACHE) {
|
||
mod.enableCompileCache();
|
||
return true;
|
||
}
|
||
} catch (_) { /* unsupported */ }
|
||
return false;
|
||
}
|
||
|
||
module.exports = {
|
||
readFastCache,
|
||
enableCompileCacheBestEffort,
|
||
__sentinel: 'P1-FAST-CACHE-V1',
|
||
};
|