dpth 0.1.0 → 0.3.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/dist/adapter-sqlite.d.ts +56 -0
- package/dist/adapter-sqlite.d.ts.map +1 -0
- package/dist/adapter-sqlite.js +234 -0
- package/dist/adapter-sqlite.js.map +1 -0
- package/dist/adapter-vector.d.ts +59 -0
- package/dist/adapter-vector.d.ts.map +1 -0
- package/dist/adapter-vector.js +168 -0
- package/dist/adapter-vector.js.map +1 -0
- package/dist/dpth.d.ts +178 -0
- package/dist/dpth.d.ts.map +1 -0
- package/dist/dpth.js +557 -0
- package/dist/dpth.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/storage.d.ts +107 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +136 -0
- package/dist/storage.js.map +1 -0
- package/package.json +26 -2
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dpth.io SQLite Storage Adapter
|
|
3
|
+
*
|
|
4
|
+
* Persistent storage using SQLite via better-sqlite3.
|
|
5
|
+
* Provides ACID transactions, SQL queries, and disk persistence.
|
|
6
|
+
*
|
|
7
|
+
* Requires: npm install better-sqlite3
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* import { configure } from 'dpth/storage';
|
|
11
|
+
* import { SQLiteAdapter } from 'dpth/adapter-sqlite';
|
|
12
|
+
* configure({ adapter: new SQLiteAdapter('./dpth.db') });
|
|
13
|
+
*/
|
|
14
|
+
import type { StorageAdapter, QueryFilter } from './storage.js';
|
|
15
|
+
export interface SQLiteAdapterOptions {
|
|
16
|
+
/** Path to database file (use ':memory:' for in-memory) */
|
|
17
|
+
path: string;
|
|
18
|
+
/** Enable WAL mode for better concurrent read performance (default: true) */
|
|
19
|
+
wal?: boolean;
|
|
20
|
+
/** Serialize values as JSON (default: true) */
|
|
21
|
+
json?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export declare class SQLiteAdapter implements StorageAdapter {
|
|
24
|
+
private db;
|
|
25
|
+
private ready;
|
|
26
|
+
private stmtCache;
|
|
27
|
+
private opts;
|
|
28
|
+
constructor(pathOrOpts: string | SQLiteAdapterOptions);
|
|
29
|
+
private init;
|
|
30
|
+
private ensureReady;
|
|
31
|
+
private stmt;
|
|
32
|
+
private serialize;
|
|
33
|
+
private deserialize;
|
|
34
|
+
get(collection: string, key: string): Promise<unknown | undefined>;
|
|
35
|
+
put(collection: string, key: string, value: unknown): Promise<void>;
|
|
36
|
+
delete(collection: string, key: string): Promise<boolean>;
|
|
37
|
+
has(collection: string, key: string): Promise<boolean>;
|
|
38
|
+
query(filter: QueryFilter): Promise<unknown[]>;
|
|
39
|
+
keys(collection: string): Promise<string[]>;
|
|
40
|
+
count(collection: string): Promise<number>;
|
|
41
|
+
clear(collection?: string): Promise<void>;
|
|
42
|
+
close(): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Run a batch of operations in a transaction (SQLite-specific)
|
|
45
|
+
*/
|
|
46
|
+
transaction<T>(fn: () => Promise<T>): Promise<T>;
|
|
47
|
+
/**
|
|
48
|
+
* Get database stats (SQLite-specific)
|
|
49
|
+
*/
|
|
50
|
+
stats(): Promise<{
|
|
51
|
+
collections: Record<string, number>;
|
|
52
|
+
totalRows: number;
|
|
53
|
+
fileSizeBytes: number;
|
|
54
|
+
}>;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=adapter-sqlite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-sqlite.d.ts","sourceRoot":"","sources":["../src/adapter-sqlite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAsBhE,MAAM,WAAW,oBAAoB;IACnC,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,6EAA6E;IAC7E,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,+CAA+C;IAC/C,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,qBAAa,aAAc,YAAW,cAAc;IAClD,OAAO,CAAC,EAAE,CAAM;IAChB,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,IAAI,CAAiC;gBAEjC,UAAU,EAAE,MAAM,GAAG,oBAAoB;YASvC,IAAI;YAwBJ,WAAW;IAIzB,OAAO,CAAC,IAAI;IASZ,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,WAAW;IAgBb,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;IAOlE,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAWnE,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAOzD,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAOtD,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IA0D9C,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAO3C,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAO1C,KAAK,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASzC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAM5B;;OAEG;IACG,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAMtD;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;CAsB1G"}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dpth.io SQLite Storage Adapter
|
|
3
|
+
*
|
|
4
|
+
* Persistent storage using SQLite via better-sqlite3.
|
|
5
|
+
* Provides ACID transactions, SQL queries, and disk persistence.
|
|
6
|
+
*
|
|
7
|
+
* Requires: npm install better-sqlite3
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* import { configure } from 'dpth/storage';
|
|
11
|
+
* import { SQLiteAdapter } from 'dpth/adapter-sqlite';
|
|
12
|
+
* configure({ adapter: new SQLiteAdapter('./dpth.db') });
|
|
13
|
+
*/
|
|
14
|
+
// Dynamic import to avoid hard dependency — no type import needed
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
16
|
+
let Database;
|
|
17
|
+
async function loadSqlite() {
|
|
18
|
+
if (Database)
|
|
19
|
+
return Database;
|
|
20
|
+
try {
|
|
21
|
+
// Dynamic import — only fails if better-sqlite3 not installed
|
|
22
|
+
const mod = await Function('return import("better-sqlite3")')();
|
|
23
|
+
Database = mod.default || mod;
|
|
24
|
+
return Database;
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
throw new Error('better-sqlite3 is required for SQLiteAdapter. Install it:\n' +
|
|
28
|
+
' npm install better-sqlite3\n' +
|
|
29
|
+
' npm install -D @types/better-sqlite3');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export class SQLiteAdapter {
|
|
33
|
+
db;
|
|
34
|
+
ready;
|
|
35
|
+
stmtCache = new Map();
|
|
36
|
+
opts;
|
|
37
|
+
constructor(pathOrOpts) {
|
|
38
|
+
const opts = typeof pathOrOpts === 'string'
|
|
39
|
+
? { path: pathOrOpts, wal: true, json: true }
|
|
40
|
+
: { wal: true, json: true, ...pathOrOpts };
|
|
41
|
+
this.opts = opts;
|
|
42
|
+
this.ready = this.init();
|
|
43
|
+
}
|
|
44
|
+
async init() {
|
|
45
|
+
const Sqlite = await loadSqlite();
|
|
46
|
+
this.db = new Sqlite(this.opts.path);
|
|
47
|
+
if (this.opts.wal) {
|
|
48
|
+
this.db.pragma('journal_mode = WAL');
|
|
49
|
+
}
|
|
50
|
+
this.db.pragma('foreign_keys = ON');
|
|
51
|
+
// Create the universal key-value table with collection support
|
|
52
|
+
this.db.exec(`
|
|
53
|
+
CREATE TABLE IF NOT EXISTS dpth_store (
|
|
54
|
+
collection TEXT NOT NULL,
|
|
55
|
+
key TEXT NOT NULL,
|
|
56
|
+
value TEXT NOT NULL,
|
|
57
|
+
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
58
|
+
updated_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
59
|
+
PRIMARY KEY (collection, key)
|
|
60
|
+
);
|
|
61
|
+
CREATE INDEX IF NOT EXISTS idx_dpth_collection ON dpth_store(collection);
|
|
62
|
+
CREATE INDEX IF NOT EXISTS idx_dpth_updated ON dpth_store(collection, updated_at);
|
|
63
|
+
`);
|
|
64
|
+
}
|
|
65
|
+
async ensureReady() {
|
|
66
|
+
await this.ready;
|
|
67
|
+
}
|
|
68
|
+
stmt(sql) {
|
|
69
|
+
let s = this.stmtCache.get(sql);
|
|
70
|
+
if (!s) {
|
|
71
|
+
s = this.db.prepare(sql);
|
|
72
|
+
this.stmtCache.set(sql, s);
|
|
73
|
+
}
|
|
74
|
+
return s;
|
|
75
|
+
}
|
|
76
|
+
serialize(value) {
|
|
77
|
+
return this.opts.json ? JSON.stringify(value) : String(value);
|
|
78
|
+
}
|
|
79
|
+
deserialize(raw) {
|
|
80
|
+
if (!this.opts.json)
|
|
81
|
+
return raw;
|
|
82
|
+
try {
|
|
83
|
+
return JSON.parse(raw, (key, value) => {
|
|
84
|
+
// Revive Date objects
|
|
85
|
+
if (typeof value === 'string' && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(value)) {
|
|
86
|
+
const d = new Date(value);
|
|
87
|
+
if (!isNaN(d.getTime()))
|
|
88
|
+
return d;
|
|
89
|
+
}
|
|
90
|
+
return value;
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return raw;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async get(collection, key) {
|
|
98
|
+
await this.ensureReady();
|
|
99
|
+
const row = this.stmt('SELECT value FROM dpth_store WHERE collection = ? AND key = ?')
|
|
100
|
+
.get(collection, key);
|
|
101
|
+
return row ? this.deserialize(row.value) : undefined;
|
|
102
|
+
}
|
|
103
|
+
async put(collection, key, value) {
|
|
104
|
+
await this.ensureReady();
|
|
105
|
+
const serialized = this.serialize(value);
|
|
106
|
+
this.stmt(`
|
|
107
|
+
INSERT INTO dpth_store (collection, key, value, updated_at)
|
|
108
|
+
VALUES (?, ?, ?, unixepoch())
|
|
109
|
+
ON CONFLICT(collection, key)
|
|
110
|
+
DO UPDATE SET value = excluded.value, updated_at = unixepoch()
|
|
111
|
+
`).run(collection, key, serialized);
|
|
112
|
+
}
|
|
113
|
+
async delete(collection, key) {
|
|
114
|
+
await this.ensureReady();
|
|
115
|
+
const result = this.stmt('DELETE FROM dpth_store WHERE collection = ? AND key = ?')
|
|
116
|
+
.run(collection, key);
|
|
117
|
+
return result.changes > 0;
|
|
118
|
+
}
|
|
119
|
+
async has(collection, key) {
|
|
120
|
+
await this.ensureReady();
|
|
121
|
+
const row = this.stmt('SELECT 1 FROM dpth_store WHERE collection = ? AND key = ?')
|
|
122
|
+
.get(collection, key);
|
|
123
|
+
return !!row;
|
|
124
|
+
}
|
|
125
|
+
async query(filter) {
|
|
126
|
+
await this.ensureReady();
|
|
127
|
+
// Get all items in collection, then filter in JS
|
|
128
|
+
// (JSON values can't be efficiently queried in SQL without json_extract)
|
|
129
|
+
const rows = this.stmt('SELECT value FROM dpth_store WHERE collection = ?')
|
|
130
|
+
.all(filter.collection);
|
|
131
|
+
let results = rows.map(r => this.deserialize(r.value));
|
|
132
|
+
// Apply where filters
|
|
133
|
+
if (filter.where) {
|
|
134
|
+
for (const [field, value] of Object.entries(filter.where)) {
|
|
135
|
+
results = results.filter(item => {
|
|
136
|
+
const obj = item;
|
|
137
|
+
return obj[field] === value;
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// Apply comparison filters
|
|
142
|
+
if (filter.compare) {
|
|
143
|
+
for (const cmp of filter.compare) {
|
|
144
|
+
results = results.filter(item => {
|
|
145
|
+
const obj = item;
|
|
146
|
+
const fieldVal = obj[cmp.field];
|
|
147
|
+
switch (cmp.op) {
|
|
148
|
+
case 'gt': return fieldVal > cmp.value;
|
|
149
|
+
case 'gte': return fieldVal >= cmp.value;
|
|
150
|
+
case 'lt': return fieldVal < cmp.value;
|
|
151
|
+
case 'lte': return fieldVal <= cmp.value;
|
|
152
|
+
case 'ne': return fieldVal !== cmp.value;
|
|
153
|
+
case 'in': return cmp.value.includes(fieldVal);
|
|
154
|
+
case 'contains': return typeof fieldVal === 'string' && fieldVal.includes(cmp.value);
|
|
155
|
+
default: return true;
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// Apply ordering
|
|
161
|
+
if (filter.orderBy) {
|
|
162
|
+
const { field, direction } = filter.orderBy;
|
|
163
|
+
results.sort((a, b) => {
|
|
164
|
+
const aVal = a[field];
|
|
165
|
+
const bVal = b[field];
|
|
166
|
+
if (aVal === bVal)
|
|
167
|
+
return 0;
|
|
168
|
+
const cmp = aVal < bVal ? -1 : 1;
|
|
169
|
+
return direction === 'asc' ? cmp : -cmp;
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
// Apply pagination
|
|
173
|
+
if (filter.offset)
|
|
174
|
+
results = results.slice(filter.offset);
|
|
175
|
+
if (filter.limit)
|
|
176
|
+
results = results.slice(0, filter.limit);
|
|
177
|
+
return results;
|
|
178
|
+
}
|
|
179
|
+
async keys(collection) {
|
|
180
|
+
await this.ensureReady();
|
|
181
|
+
const rows = this.stmt('SELECT key FROM dpth_store WHERE collection = ?')
|
|
182
|
+
.all(collection);
|
|
183
|
+
return rows.map(r => r.key);
|
|
184
|
+
}
|
|
185
|
+
async count(collection) {
|
|
186
|
+
await this.ensureReady();
|
|
187
|
+
const row = this.stmt('SELECT COUNT(*) as cnt FROM dpth_store WHERE collection = ?')
|
|
188
|
+
.get(collection);
|
|
189
|
+
return row.cnt;
|
|
190
|
+
}
|
|
191
|
+
async clear(collection) {
|
|
192
|
+
await this.ensureReady();
|
|
193
|
+
if (collection) {
|
|
194
|
+
this.stmt('DELETE FROM dpth_store WHERE collection = ?').run(collection);
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
this.db.exec('DELETE FROM dpth_store');
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
async close() {
|
|
201
|
+
await this.ensureReady();
|
|
202
|
+
this.stmtCache.clear();
|
|
203
|
+
this.db.close();
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Run a batch of operations in a transaction (SQLite-specific)
|
|
207
|
+
*/
|
|
208
|
+
async transaction(fn) {
|
|
209
|
+
await this.ensureReady();
|
|
210
|
+
const tx = this.db.transaction(() => fn());
|
|
211
|
+
return tx();
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Get database stats (SQLite-specific)
|
|
215
|
+
*/
|
|
216
|
+
async stats() {
|
|
217
|
+
await this.ensureReady();
|
|
218
|
+
const rows = this.stmt('SELECT collection, COUNT(*) as cnt FROM dpth_store GROUP BY collection').all();
|
|
219
|
+
const collections = {};
|
|
220
|
+
let total = 0;
|
|
221
|
+
for (const row of rows) {
|
|
222
|
+
collections[row.collection] = row.cnt;
|
|
223
|
+
total += row.cnt;
|
|
224
|
+
}
|
|
225
|
+
const pageCount = this.db.pragma('page_count', { simple: true });
|
|
226
|
+
const pageSize = this.db.pragma('page_size', { simple: true });
|
|
227
|
+
return {
|
|
228
|
+
collections,
|
|
229
|
+
totalRows: total,
|
|
230
|
+
fileSizeBytes: pageCount * pageSize,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=adapter-sqlite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-sqlite.js","sourceRoot":"","sources":["../src/adapter-sqlite.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dpth.io Vector Storage Adapter
|
|
3
|
+
*
|
|
4
|
+
* Adds semantic search capabilities on top of any base adapter.
|
|
5
|
+
* Uses cosine similarity for nearest-neighbor search.
|
|
6
|
+
*
|
|
7
|
+
* Two implementations:
|
|
8
|
+
* 1. MemoryVectorAdapter — in-memory, zero deps, good for prototyping
|
|
9
|
+
* 2. (future) SqliteVecAdapter — persistent vectors via sqlite-vec
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* import { configure } from 'dpth/storage';
|
|
13
|
+
* import { MemoryVectorAdapter } from 'dpth/adapter-vector';
|
|
14
|
+
* configure({ adapter: new MemoryVectorAdapter() });
|
|
15
|
+
*/
|
|
16
|
+
import type { StorageAdapter, VectorAdapter, VectorResult, QueryFilter } from './storage.js';
|
|
17
|
+
import { MemoryAdapter } from './storage.js';
|
|
18
|
+
/**
|
|
19
|
+
* In-memory vector adapter with brute-force cosine similarity search.
|
|
20
|
+
* Good for up to ~100K vectors. For larger scale, use SqliteVecAdapter.
|
|
21
|
+
*/
|
|
22
|
+
export declare class MemoryVectorAdapter extends MemoryAdapter implements VectorAdapter {
|
|
23
|
+
private vectors;
|
|
24
|
+
private getVectorCollection;
|
|
25
|
+
putVector(collection: string, key: string, vector: number[], metadata?: Record<string, unknown>): Promise<void>;
|
|
26
|
+
searchVector(collection: string, vector: number[], topK: number, minScore?: number): Promise<VectorResult[]>;
|
|
27
|
+
dimensions(collection: string): Promise<number | undefined>;
|
|
28
|
+
clear(collection?: string): Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Wraps any base StorageAdapter and adds vector search on top.
|
|
32
|
+
* Vectors stored in memory, base data stored via the underlying adapter.
|
|
33
|
+
*
|
|
34
|
+
* Useful pattern: wrap a SQLiteAdapter to get persistence + vectors
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* import { SQLiteAdapter } from 'dpth/adapter-sqlite';
|
|
38
|
+
* import { VectorOverlay } from 'dpth/adapter-vector';
|
|
39
|
+
* const adapter = new VectorOverlay(new SQLiteAdapter('./data.db'));
|
|
40
|
+
*/
|
|
41
|
+
export declare class VectorOverlay implements VectorAdapter {
|
|
42
|
+
private base;
|
|
43
|
+
private vectors;
|
|
44
|
+
constructor(base: StorageAdapter);
|
|
45
|
+
private getVectorCollection;
|
|
46
|
+
putVector(collection: string, key: string, vector: number[], metadata?: Record<string, unknown>): Promise<void>;
|
|
47
|
+
searchVector(collection: string, vector: number[], topK: number, minScore?: number): Promise<VectorResult[]>;
|
|
48
|
+
dimensions(collection: string): Promise<number | undefined>;
|
|
49
|
+
get(collection: string, key: string): Promise<unknown>;
|
|
50
|
+
put(collection: string, key: string, value: unknown): Promise<void>;
|
|
51
|
+
delete(collection: string, key: string): Promise<boolean>;
|
|
52
|
+
has(collection: string, key: string): Promise<boolean>;
|
|
53
|
+
query(filter: QueryFilter): Promise<unknown[]>;
|
|
54
|
+
keys(collection: string): Promise<string[]>;
|
|
55
|
+
count(collection: string): Promise<number>;
|
|
56
|
+
clear(collection?: string): Promise<void>;
|
|
57
|
+
close(): Promise<void>;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=adapter-vector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-vector.d.ts","sourceRoot":"","sources":["../src/adapter-vector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC7F,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAU7C;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,aAAc,YAAW,aAAa;IAC7E,OAAO,CAAC,OAAO,CAAoC;IAEnD,OAAO,CAAC,mBAAmB;IASrB,SAAS,CACb,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EAAE,EAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC;IAiBV,YAAY,CAChB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,EAAE,MAAM,EACZ,QAAQ,GAAE,MAAU,GACnB,OAAO,CAAC,YAAY,EAAE,CAAC;IAepB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAM3D,KAAK,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAQhD;AAuBD;;;;;;;;;;GAUG;AACH,qBAAa,aAAc,YAAW,aAAa;IAGrC,OAAO,CAAC,IAAI;IAFxB,OAAO,CAAC,OAAO,CAAoC;gBAE/B,IAAI,EAAE,cAAc;IAExC,OAAO,CAAC,mBAAmB;IAWrB,SAAS,CACb,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EAAE,EAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC;IAeV,YAAY,CAChB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,EAAE,MAAM,EACZ,QAAQ,GAAE,MAAU,GACnB,OAAO,CAAC,YAAY,EAAE,CAAC;IAepB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAQjE,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;IACnC,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;IACnD,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;IACtC,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;IACnC,KAAK,CAAC,MAAM,EAAE,WAAW;IACzB,IAAI,CAAC,UAAU,EAAE,MAAM;IACvB,KAAK,CAAC,UAAU,EAAE,MAAM;IAElB,KAAK,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASzC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAI7B"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dpth.io Vector Storage Adapter
|
|
3
|
+
*
|
|
4
|
+
* Adds semantic search capabilities on top of any base adapter.
|
|
5
|
+
* Uses cosine similarity for nearest-neighbor search.
|
|
6
|
+
*
|
|
7
|
+
* Two implementations:
|
|
8
|
+
* 1. MemoryVectorAdapter — in-memory, zero deps, good for prototyping
|
|
9
|
+
* 2. (future) SqliteVecAdapter — persistent vectors via sqlite-vec
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* import { configure } from 'dpth/storage';
|
|
13
|
+
* import { MemoryVectorAdapter } from 'dpth/adapter-vector';
|
|
14
|
+
* configure({ adapter: new MemoryVectorAdapter() });
|
|
15
|
+
*/
|
|
16
|
+
import { MemoryAdapter } from './storage.js';
|
|
17
|
+
/**
|
|
18
|
+
* In-memory vector adapter with brute-force cosine similarity search.
|
|
19
|
+
* Good for up to ~100K vectors. For larger scale, use SqliteVecAdapter.
|
|
20
|
+
*/
|
|
21
|
+
export class MemoryVectorAdapter extends MemoryAdapter {
|
|
22
|
+
vectors = new Map(); // collection → entries
|
|
23
|
+
getVectorCollection(collection) {
|
|
24
|
+
let col = this.vectors.get(collection);
|
|
25
|
+
if (!col) {
|
|
26
|
+
col = [];
|
|
27
|
+
this.vectors.set(collection, col);
|
|
28
|
+
}
|
|
29
|
+
return col;
|
|
30
|
+
}
|
|
31
|
+
async putVector(collection, key, vector, metadata) {
|
|
32
|
+
const col = this.getVectorCollection(collection);
|
|
33
|
+
// Update existing or add new
|
|
34
|
+
const existing = col.findIndex(e => e.key === key);
|
|
35
|
+
const entry = { key, vector, metadata: metadata || {} };
|
|
36
|
+
if (existing >= 0) {
|
|
37
|
+
col[existing] = entry;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
col.push(entry);
|
|
41
|
+
}
|
|
42
|
+
// Also store metadata in the base KV store for query support
|
|
43
|
+
await this.put(collection, key, { ...metadata, _hasVector: true });
|
|
44
|
+
}
|
|
45
|
+
async searchVector(collection, vector, topK, minScore = 0) {
|
|
46
|
+
const col = this.getVectorCollection(collection);
|
|
47
|
+
const scored = [];
|
|
48
|
+
for (const entry of col) {
|
|
49
|
+
const score = cosineSimilarity(vector, entry.vector);
|
|
50
|
+
if (score >= minScore) {
|
|
51
|
+
scored.push({ key: entry.key, score, metadata: entry.metadata });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
scored.sort((a, b) => b.score - a.score);
|
|
55
|
+
return scored.slice(0, topK);
|
|
56
|
+
}
|
|
57
|
+
async dimensions(collection) {
|
|
58
|
+
const col = this.vectors.get(collection);
|
|
59
|
+
if (!col || col.length === 0)
|
|
60
|
+
return undefined;
|
|
61
|
+
return col[0].vector.length;
|
|
62
|
+
}
|
|
63
|
+
async clear(collection) {
|
|
64
|
+
await super.clear(collection);
|
|
65
|
+
if (collection) {
|
|
66
|
+
this.vectors.delete(collection);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
this.vectors.clear();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// ─── Cosine Similarity ───────────────────────────────
|
|
74
|
+
function cosineSimilarity(a, b) {
|
|
75
|
+
if (a.length !== b.length)
|
|
76
|
+
return 0;
|
|
77
|
+
let dot = 0;
|
|
78
|
+
let normA = 0;
|
|
79
|
+
let normB = 0;
|
|
80
|
+
for (let i = 0; i < a.length; i++) {
|
|
81
|
+
dot += a[i] * b[i];
|
|
82
|
+
normA += a[i] * a[i];
|
|
83
|
+
normB += b[i] * b[i];
|
|
84
|
+
}
|
|
85
|
+
const denom = Math.sqrt(normA) * Math.sqrt(normB);
|
|
86
|
+
return denom === 0 ? 0 : dot / denom;
|
|
87
|
+
}
|
|
88
|
+
// ─── Wrapper Adapter ─────────────────────────────────
|
|
89
|
+
/**
|
|
90
|
+
* Wraps any base StorageAdapter and adds vector search on top.
|
|
91
|
+
* Vectors stored in memory, base data stored via the underlying adapter.
|
|
92
|
+
*
|
|
93
|
+
* Useful pattern: wrap a SQLiteAdapter to get persistence + vectors
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* import { SQLiteAdapter } from 'dpth/adapter-sqlite';
|
|
97
|
+
* import { VectorOverlay } from 'dpth/adapter-vector';
|
|
98
|
+
* const adapter = new VectorOverlay(new SQLiteAdapter('./data.db'));
|
|
99
|
+
*/
|
|
100
|
+
export class VectorOverlay {
|
|
101
|
+
base;
|
|
102
|
+
vectors = new Map();
|
|
103
|
+
constructor(base) {
|
|
104
|
+
this.base = base;
|
|
105
|
+
}
|
|
106
|
+
getVectorCollection(collection) {
|
|
107
|
+
let col = this.vectors.get(collection);
|
|
108
|
+
if (!col) {
|
|
109
|
+
col = [];
|
|
110
|
+
this.vectors.set(collection, col);
|
|
111
|
+
}
|
|
112
|
+
return col;
|
|
113
|
+
}
|
|
114
|
+
// ── Vector operations ──
|
|
115
|
+
async putVector(collection, key, vector, metadata) {
|
|
116
|
+
const col = this.getVectorCollection(collection);
|
|
117
|
+
const existing = col.findIndex(e => e.key === key);
|
|
118
|
+
const entry = { key, vector, metadata: metadata || {} };
|
|
119
|
+
if (existing >= 0) {
|
|
120
|
+
col[existing] = entry;
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
col.push(entry);
|
|
124
|
+
}
|
|
125
|
+
// Store metadata in base adapter
|
|
126
|
+
await this.base.put(collection, key, { ...metadata, _hasVector: true });
|
|
127
|
+
}
|
|
128
|
+
async searchVector(collection, vector, topK, minScore = 0) {
|
|
129
|
+
const col = this.getVectorCollection(collection);
|
|
130
|
+
const scored = [];
|
|
131
|
+
for (const entry of col) {
|
|
132
|
+
const score = cosineSimilarity(vector, entry.vector);
|
|
133
|
+
if (score >= minScore) {
|
|
134
|
+
scored.push({ key: entry.key, score, metadata: entry.metadata });
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
scored.sort((a, b) => b.score - a.score);
|
|
138
|
+
return scored.slice(0, topK);
|
|
139
|
+
}
|
|
140
|
+
async dimensions(collection) {
|
|
141
|
+
const col = this.vectors.get(collection);
|
|
142
|
+
if (!col || col.length === 0)
|
|
143
|
+
return undefined;
|
|
144
|
+
return col[0].vector.length;
|
|
145
|
+
}
|
|
146
|
+
// ── Delegate base operations ──
|
|
147
|
+
get(collection, key) { return this.base.get(collection, key); }
|
|
148
|
+
put(collection, key, value) { return this.base.put(collection, key, value); }
|
|
149
|
+
delete(collection, key) { return this.base.delete(collection, key); }
|
|
150
|
+
has(collection, key) { return this.base.has(collection, key); }
|
|
151
|
+
query(filter) { return this.base.query(filter); }
|
|
152
|
+
keys(collection) { return this.base.keys(collection); }
|
|
153
|
+
count(collection) { return this.base.count(collection); }
|
|
154
|
+
async clear(collection) {
|
|
155
|
+
await this.base.clear(collection);
|
|
156
|
+
if (collection) {
|
|
157
|
+
this.vectors.delete(collection);
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
this.vectors.clear();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
async close() {
|
|
164
|
+
this.vectors.clear();
|
|
165
|
+
await this.base.close();
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=adapter-vector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-vector.js","sourceRoot":"","sources":["../src/adapter-vector.ts"],"names":[],"mappings":"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"}
|