104 lines
3.6 KiB
JavaScript
104 lines
3.6 KiB
JavaScript
|
|
/**
|
|||
|
|
* ═══════════════════════════════════════
|
|||
|
|
* HLDP-ZY://native-repo/module/step-4
|
|||
|
|
* 光湖原生数据库 · 第4步 · HLDP读取+树索引
|
|||
|
|
* ═══════════════════════════════════════
|
|||
|
|
*
|
|||
|
|
* @chain: D118 · 2026-05-31
|
|||
|
|
* @module: hldp-read-tree
|
|||
|
|
* @step: 第4步 / 共8步
|
|||
|
|
* @deploy: BS-SG-002
|
|||
|
|
*
|
|||
|
|
* @trigger:
|
|||
|
|
* 第3步能写文件了,但铸渊还需要两件事:
|
|||
|
|
* 1. 按 HLDP tree_path 读取文件内容(trace_path意图)
|
|||
|
|
* 2. 生成树形索引,每次只加载10条,恒定O(1)认知负载
|
|||
|
|
*
|
|||
|
|
* @lock:
|
|||
|
|
* ⊢ hldpRead(path) → 返回文件内容 + commit 元信息
|
|||
|
|
* ⊢ hldpTree(dir) → 返回目录列表,每层最多显示10条
|
|||
|
|
* ⊢ buildIndex() → 生成 tree-index.json,10条/层
|
|||
|
|
*
|
|||
|
|
* @why:
|
|||
|
|
* trace_path = 光之树寻址 = 铸渊大脑的核心操作
|
|||
|
|
* 不需要把整个仓库装进上下文——只读10条索引
|
|||
|
|
* 需要哪片叶子,按路径走一步就到了
|
|||
|
|
* ═══════════════════════════════════════
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
const git = require('isomorphic-git');
|
|||
|
|
const fs = require('fs');
|
|||
|
|
const path = require('path');
|
|||
|
|
|
|||
|
|
const { NATIVE_DIR } = require('./step-2-git-init');
|
|||
|
|
|
|||
|
|
// ─── hldpRead: 按路径读文件 ─────────────────────────────────
|
|||
|
|
async function hldpRead(filePath) {
|
|||
|
|
const fullPath = path.join(NATIVE_DIR, filePath);
|
|||
|
|
if (!fs.existsSync(fullPath)) {
|
|||
|
|
return { ok: false, error: 'NOT_FOUND', path: filePath };
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const content = fs.readFileSync(fullPath, 'utf8');
|
|||
|
|
const log = await git.log({ fs, dir: NATIVE_DIR });
|
|||
|
|
const lastCommit = log.find(c => c.commit.message.includes(filePath));
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
ok: true,
|
|||
|
|
path: filePath,
|
|||
|
|
content,
|
|||
|
|
sha: lastCommit ? lastCommit.oid : null,
|
|||
|
|
size: content.length,
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ─── hldpTree: 按目录列文件 ─────────────────────────────────
|
|||
|
|
async function hldpTree(dirPath) {
|
|||
|
|
const fullPath = path.join(NATIVE_DIR, dirPath || '');
|
|||
|
|
if (!fs.existsSync(fullPath)) {
|
|||
|
|
return { ok: false, error: 'NOT_FOUND', path: dirPath };
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const entries = fs.readdirSync(fullPath, { withFileTypes: true });
|
|||
|
|
const list = entries
|
|||
|
|
.filter(e => !e.name.startsWith('.') && e.name !== 'node_modules' && e.name !== 'package.json')
|
|||
|
|
.map(e => ({
|
|||
|
|
name: e.name,
|
|||
|
|
type: e.isDirectory() ? 'dir' : 'file',
|
|||
|
|
path: path.join(dirPath || '', e.name),
|
|||
|
|
}));
|
|||
|
|
|
|||
|
|
return { ok: true, path: dirPath, count: list.length, entries: list };
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ─── buildIndex: 生成树索引(10条/层) ──────────────────────
|
|||
|
|
async function buildIndex() {
|
|||
|
|
async function walk(dir, depth) {
|
|||
|
|
if (depth > 3) return [];
|
|||
|
|
const { entries } = await hldpTree(dir);
|
|||
|
|
if (!entries || entries.length === 0) return [];
|
|||
|
|
|
|||
|
|
return entries.slice(0, 10).map(({ name, type, path: p }) => ({
|
|||
|
|
name,
|
|||
|
|
type,
|
|||
|
|
path: p,
|
|||
|
|
isBranch: type === 'dir',
|
|||
|
|
}));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const root = await walk('', 0);
|
|||
|
|
const index = {
|
|||
|
|
_type: 'HLDP_TREE_INDEX',
|
|||
|
|
_version: 'v1.0',
|
|||
|
|
_updated: new Date().toISOString(),
|
|||
|
|
_principle: '每层10行,恒定O(1)认知负载',
|
|||
|
|
root,
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const indexPath = path.join(NATIVE_DIR, 'tree-index.json');
|
|||
|
|
fs.writeFileSync(indexPath, JSON.stringify(index, null, 2), 'utf8');
|
|||
|
|
return index;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
module.exports = { hldpRead, hldpTree, buildIndex };
|