autosnippet
Version:
Extract code patterns into a knowledge base for AI coding assistants
135 lines (134 loc) • 3.8 kB
JavaScript
/**
* Relations — 关系图值对象
*
* 统一为分桶结构(非扁平数组)。
* 每个桶存储 [{ target, description }] 格式的关系列表。
*/
/** 所有合法的关系桶名 (snake_case) */
export const RELATION_BUCKETS = [
'inherits', // 继承
'implements', // 实现接口/协议
'calls', // 调用
'depends_on', // 依赖
'data_flow', // 数据流向
'conflicts', // 冲突
'extends', // 扩展
'related', // 弱关联
'alternative', // 替代方案
'prerequisite', // 前置条件
'deprecated_by', // 被取代
'solves', // 解决问题
'enforces', // 强制约束
'references', // 引用
];
export class Relations {
_b;
constructor(buckets = {}) {
/** >>} */
this._b = {};
for (const k of RELATION_BUCKETS) {
const vals = buckets[k] || [];
this._b[k] = vals
.map((r) => {
// 兼容字符串数组:AI prompt 可能返回 ["recipeName"] 而非 [{target,description}]
if (typeof r === 'string') {
return r.trim() ? { target: r.trim(), description: '' } : null;
}
return { target: r.target || '', description: r.description || '' };
})
.filter((entry) => entry !== null);
}
}
/** 从任意输入构造 Relations */
static from(input) {
if (input instanceof Relations) {
return input;
}
if (!input) {
return new Relations();
}
if (typeof input === 'string') {
try {
input = JSON.parse(input);
}
catch {
return new Relations();
}
}
if (Array.isArray(input)) {
// 扁平数组 → 自动分桶
const buckets = {};
for (const rel of input) {
const item = rel;
const bucket = item.type || 'related';
if (!buckets[bucket]) {
buckets[bucket] = [];
}
buckets[bucket].push({
target: item.target || '',
description: item.description || '',
});
}
return new Relations(buckets);
}
return new Relations(input);
}
/**
* 扁平视图(仅 Dashboard 渲染用)
* @returns >}
*/
toFlatArray() {
const result = [];
for (const [type, list] of Object.entries(this._b)) {
for (const r of list) {
result.push({ type, ...r });
}
}
return result;
}
/**
* 获取指定桶
* @returns >}
*/
getByType(type) {
return this._b[type] || [];
}
/** 是否为空 */
isEmpty() {
return Object.values(this._b).every((l) => l.length === 0);
}
/**
* 添加关系
* @param type 桶名
* @param target 目标
*/
add(type, target, description = '') {
if (!this._b[type]) {
this._b[type] = [];
}
if (!this._b[type].some((r) => r.target === target)) {
this._b[type].push({ target, description });
}
return this;
}
/**
* 移除关系
* @param type 桶名
* @param target 目标
*/
remove(type, target) {
if (this._b[type]) {
this._b[type] = this._b[type].filter((r) => r.target !== target);
}
return this;
}
/** 转换为 wire format JSON (分桶) */
toJSON() {
return { ...this._b };
}
/** 从 wire format 创建 */
static fromJSON(data) {
return Relations.from(data);
}
}
export default Relations;