@aalis/plugin-vectorstore-flat 0.1.0
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/README.md +21 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +134 -0
- package/dist/index.js.map +1 -0
- package/package.json +36 -0
package/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# @aalis/plugin-vectorstore-flat
|
|
2
|
+
|
|
3
|
+
运行时插件
|
|
4
|
+
|
|
5
|
+
## 角色
|
|
6
|
+
|
|
7
|
+
运行时插件
|
|
8
|
+
|
|
9
|
+
## 安装
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pnpm add @aalis/plugin-vectorstore-flat
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## 文档
|
|
16
|
+
|
|
17
|
+
详见 [docs/plugins/plugin-vectorstore-flat.md](../../docs/plugins/plugin-vectorstore-flat.md)。
|
|
18
|
+
|
|
19
|
+
## 许可
|
|
20
|
+
|
|
21
|
+
见仓库根目录 LICENSE。
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ConfigSchema, Context } from '@aalis/core';
|
|
2
|
+
export declare const name = "@aalis/plugin-vectorstore-flat";
|
|
3
|
+
export declare const displayName = "Flat \u5411\u91CF\u5E93";
|
|
4
|
+
export declare const subsystem = "embedding";
|
|
5
|
+
export declare const provides: string[];
|
|
6
|
+
export declare const configSchema: ConfigSchema;
|
|
7
|
+
export declare const defaultConfig: {
|
|
8
|
+
path: string;
|
|
9
|
+
};
|
|
10
|
+
export declare function apply(ctx: Context, config: Record<string, unknown>): Promise<void>;
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAMzD,eAAO,MAAM,IAAI,mCAAmC,CAAC;AACrD,eAAO,MAAM,WAAW,4BAAa,CAAC;AACtC,eAAO,MAAM,SAAS,cAAc,CAAC;AACrC,eAAO,MAAM,QAAQ,UAAkB,CAAC;AAExC,eAAO,MAAM,YAAY,EAAE,YAO1B,CAAC;AAEF,eAAO,MAAM,aAAa;;CAEzB,CAAC;AAqHF,wBAAsB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BxF"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { createStorageGateway } from '@aalis/plugin-storage-api';
|
|
2
|
+
// ===== 插件元数据 =====
|
|
3
|
+
export const name = '@aalis/plugin-vectorstore-flat';
|
|
4
|
+
export const displayName = 'Flat 向量库';
|
|
5
|
+
export const subsystem = 'embedding';
|
|
6
|
+
export const provides = ['vectorstore'];
|
|
7
|
+
export const configSchema = {
|
|
8
|
+
path: {
|
|
9
|
+
type: 'string',
|
|
10
|
+
label: '存储目录',
|
|
11
|
+
default: 'data:/vectorstore',
|
|
12
|
+
description: 'JSON 向量文件存储目录(storage URI)。也兼容旧格式 “data/vectorstore”。',
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
export const defaultConfig = {
|
|
16
|
+
path: 'data:/vectorstore',
|
|
17
|
+
};
|
|
18
|
+
// ===== 向量计算 =====
|
|
19
|
+
function dotProduct(a, b) {
|
|
20
|
+
let sum = 0;
|
|
21
|
+
for (let i = 0; i < a.length; i++)
|
|
22
|
+
sum += a[i] * b[i];
|
|
23
|
+
return sum;
|
|
24
|
+
}
|
|
25
|
+
function normalize(vec) {
|
|
26
|
+
let norm = 0;
|
|
27
|
+
for (const v of vec)
|
|
28
|
+
norm += v * v;
|
|
29
|
+
norm = Math.sqrt(norm);
|
|
30
|
+
if (norm === 0)
|
|
31
|
+
return vec;
|
|
32
|
+
return vec.map(v => v / norm);
|
|
33
|
+
}
|
|
34
|
+
class FlatVectorStore {
|
|
35
|
+
logger;
|
|
36
|
+
entries = [];
|
|
37
|
+
storage;
|
|
38
|
+
dataUri;
|
|
39
|
+
dirty = false;
|
|
40
|
+
constructor(storage, dataUri, logger) {
|
|
41
|
+
this.logger = logger;
|
|
42
|
+
this.storage = storage;
|
|
43
|
+
this.dataUri = dataUri;
|
|
44
|
+
}
|
|
45
|
+
/** 启动加载(由 apply 调用) */
|
|
46
|
+
async init() {
|
|
47
|
+
try {
|
|
48
|
+
const raw = (await this.storage.readFile(this.dataUri, 'utf-8'));
|
|
49
|
+
this.entries = JSON.parse(raw);
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
53
|
+
// 文件不存在 = 冷启动,不警告;其他错误才警
|
|
54
|
+
if (!/ENOENT|not found|不存在/i.test(msg)) {
|
|
55
|
+
this.logger?.warn(`向量数据文件损坏,将从空数据开始: ${msg}`);
|
|
56
|
+
}
|
|
57
|
+
this.entries = [];
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async size() {
|
|
61
|
+
return this.entries.length;
|
|
62
|
+
}
|
|
63
|
+
async add(vector, metadata) {
|
|
64
|
+
this.entries.push({ vector: normalize(vector), metadata });
|
|
65
|
+
this.dirty = true;
|
|
66
|
+
}
|
|
67
|
+
async clear() {
|
|
68
|
+
this.entries = [];
|
|
69
|
+
this.dirty = true;
|
|
70
|
+
await this.save();
|
|
71
|
+
}
|
|
72
|
+
async deleteByFilter(filter) {
|
|
73
|
+
const before = this.entries.length;
|
|
74
|
+
this.entries = this.entries.filter(e => {
|
|
75
|
+
for (const [key, value] of Object.entries(filter)) {
|
|
76
|
+
if (e.metadata[key] !== value)
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
return false;
|
|
80
|
+
});
|
|
81
|
+
const deleted = before - this.entries.length;
|
|
82
|
+
if (deleted > 0)
|
|
83
|
+
this.dirty = true;
|
|
84
|
+
return deleted;
|
|
85
|
+
}
|
|
86
|
+
async search(queryVector, topK) {
|
|
87
|
+
if (this.entries.length === 0)
|
|
88
|
+
return [];
|
|
89
|
+
const q = normalize(queryVector);
|
|
90
|
+
const scored = this.entries.map(e => ({
|
|
91
|
+
score: dotProduct(q, e.vector),
|
|
92
|
+
metadata: e.metadata,
|
|
93
|
+
}));
|
|
94
|
+
scored.sort((a, b) => b.score - a.score);
|
|
95
|
+
return scored.slice(0, Math.min(topK, scored.length));
|
|
96
|
+
}
|
|
97
|
+
async save() {
|
|
98
|
+
if (!this.dirty)
|
|
99
|
+
return;
|
|
100
|
+
try {
|
|
101
|
+
await this.storage.writeFile(this.dataUri, JSON.stringify(this.entries));
|
|
102
|
+
this.dirty = false;
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
106
|
+
this.logger?.warn(`向量数据保存失败: ${msg}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// ===== 插件入口 =====
|
|
111
|
+
export async function apply(ctx, config) {
|
|
112
|
+
const storeConfig = {
|
|
113
|
+
path: config.path ?? 'data:/vectorstore',
|
|
114
|
+
};
|
|
115
|
+
// 兼容旧格式 “data/vectorstore”
|
|
116
|
+
function toUri(input) {
|
|
117
|
+
if (input.includes(':/'))
|
|
118
|
+
return input;
|
|
119
|
+
const s = input.trim().replace(/^\.?\/+/, '');
|
|
120
|
+
const idx = s.indexOf('/');
|
|
121
|
+
return idx > 0 ? `${s.slice(0, idx)}:/${s.slice(idx + 1)}` : `${s}:/`;
|
|
122
|
+
}
|
|
123
|
+
const dirUri = toUri(storeConfig.path);
|
|
124
|
+
const dataUri = dirUri.endsWith('/') ? `${dirUri}vectors.json` : `${dirUri}/vectors.json`;
|
|
125
|
+
const storage = createStorageGateway(ctx);
|
|
126
|
+
const store = new FlatVectorStore(storage, dataUri, ctx.logger);
|
|
127
|
+
await store.init();
|
|
128
|
+
ctx.logger.info(`向量数据库已加载: ${await store.size()} 条记录, 存储 URI=${dataUri}`);
|
|
129
|
+
ctx.provide('vectorstore', store);
|
|
130
|
+
ctx.onDispose(() => {
|
|
131
|
+
void store.save();
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@aalis/plugin-vectorstore-flat",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"aalis-plugin"
|
|
7
|
+
],
|
|
8
|
+
"main": "dist/index.js",
|
|
9
|
+
"types": "dist/index.d.ts",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@aalis/plugin-storage-api": "^0.1.0"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@types/node": "^22.0.0",
|
|
18
|
+
"typescript": "^5.7.0",
|
|
19
|
+
"@aalis/plugin-vectorstore-api": "0.1.0",
|
|
20
|
+
"@aalis/core": "0.1.0"
|
|
21
|
+
},
|
|
22
|
+
"peerDependencies": {
|
|
23
|
+
"@aalis/core": "^0.1.0"
|
|
24
|
+
},
|
|
25
|
+
"aalis": {
|
|
26
|
+
"service": {
|
|
27
|
+
"provides": [
|
|
28
|
+
"vectorstore"
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsc",
|
|
34
|
+
"dev": "tsc --watch"
|
|
35
|
+
}
|
|
36
|
+
}
|