@zauso-ai/capstan-db 0.1.4 → 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.
Files changed (67) hide show
  1. package/dist/client.d.ts +31 -18
  2. package/dist/client.d.ts.map +1 -1
  3. package/dist/client.js +300 -24
  4. package/dist/client.js.map +1 -1
  5. package/dist/crud.d.ts +14 -0
  6. package/dist/crud.d.ts.map +1 -1
  7. package/dist/crud.js +49 -39
  8. package/dist/crud.js.map +1 -1
  9. package/dist/dialect.d.ts +25 -0
  10. package/dist/dialect.d.ts.map +1 -0
  11. package/dist/dialect.js +208 -0
  12. package/dist/dialect.js.map +1 -0
  13. package/dist/embedding.d.ts +63 -0
  14. package/dist/embedding.d.ts.map +1 -0
  15. package/dist/embedding.js +61 -0
  16. package/dist/embedding.js.map +1 -0
  17. package/dist/index.d.ts +14 -4
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +6 -2
  20. package/dist/index.js.map +1 -1
  21. package/dist/migrate.d.ts +44 -23
  22. package/dist/migrate.d.ts.map +1 -1
  23. package/dist/migrate.js +308 -125
  24. package/dist/migrate.js.map +1 -1
  25. package/dist/model.d.ts +9 -0
  26. package/dist/model.d.ts.map +1 -1
  27. package/dist/model.js +13 -0
  28. package/dist/model.js.map +1 -1
  29. package/dist/naming.d.ts +37 -0
  30. package/dist/naming.d.ts.map +1 -0
  31. package/dist/naming.js +196 -0
  32. package/dist/naming.js.map +1 -0
  33. package/dist/runtime.d.ts +51 -0
  34. package/dist/runtime.d.ts.map +1 -0
  35. package/dist/runtime.js +490 -0
  36. package/dist/runtime.js.map +1 -0
  37. package/dist/schema.d.ts +2 -12
  38. package/dist/schema.d.ts.map +1 -1
  39. package/dist/schema.js +199 -105
  40. package/dist/schema.js.map +1 -1
  41. package/dist/search.d.ts +52 -0
  42. package/dist/search.d.ts.map +1 -0
  43. package/dist/search.js +110 -0
  44. package/dist/search.js.map +1 -0
  45. package/dist/types.d.ts +5 -2
  46. package/dist/types.d.ts.map +1 -1
  47. package/dist/vector-store-memory.d.ts +31 -0
  48. package/dist/vector-store-memory.d.ts.map +1 -0
  49. package/dist/vector-store-memory.js +125 -0
  50. package/dist/vector-store-memory.js.map +1 -0
  51. package/dist/vector-store-pgvector.d.ts +46 -0
  52. package/dist/vector-store-pgvector.d.ts.map +1 -0
  53. package/dist/vector-store-pgvector.js +215 -0
  54. package/dist/vector-store-pgvector.js.map +1 -0
  55. package/dist/vector-store-sqlite.d.ts +51 -0
  56. package/dist/vector-store-sqlite.d.ts.map +1 -0
  57. package/dist/vector-store-sqlite.js +203 -0
  58. package/dist/vector-store-sqlite.js.map +1 -0
  59. package/dist/vector-store.d.ts +79 -0
  60. package/dist/vector-store.d.ts.map +1 -0
  61. package/dist/vector-store.js +5 -0
  62. package/dist/vector-store.js.map +1 -0
  63. package/dist/write.d.ts +15 -0
  64. package/dist/write.d.ts.map +1 -0
  65. package/dist/write.js +156 -0
  66. package/dist/write.js.map +1 -0
  67. package/package.json +17 -4
@@ -0,0 +1,203 @@
1
+ // ---------------------------------------------------------------------------
2
+ // SqliteVectorStore — SQLite-backed vector search with JSON array storage
3
+ // ---------------------------------------------------------------------------
4
+ //
5
+ // Vectors are persisted as JSON arrays in a `capstan_vectors` table. On
6
+ // search, all matching rows are loaded into memory and scored with the same
7
+ // cosine-distance function used by the in-memory store. This gives durable
8
+ // storage without requiring pgvector, at the cost of O(n) scan time.
9
+ //
10
+ // Suitable for moderate datasets where PostgreSQL is overkill but persistence
11
+ // across restarts is desired.
12
+ // ---------------------------------------------------------------------------
13
+ import { cosineDistance } from "./search.js";
14
+ /** Simple whitespace tokeniser with lower-casing and deduplication. */
15
+ function tokenize(text) {
16
+ return [
17
+ ...new Set(text
18
+ .toLowerCase()
19
+ .split(/\W+/)
20
+ .filter((t) => t.length > 0)),
21
+ ];
22
+ }
23
+ function keywordOverlap(queryTerms, text) {
24
+ if (queryTerms.length === 0)
25
+ return 0;
26
+ const docTokens = new Set(tokenize(text));
27
+ let hits = 0;
28
+ for (const term of queryTerms) {
29
+ if (docTokens.has(term))
30
+ hits++;
31
+ }
32
+ return hits / queryTerms.length;
33
+ }
34
+ function matchesFilter(metadata, filter) {
35
+ for (const [key, value] of Object.entries(filter)) {
36
+ const actual = metadata[key];
37
+ if (Array.isArray(value)) {
38
+ if (!value.includes(actual))
39
+ return false;
40
+ }
41
+ else if (actual !== value) {
42
+ return false;
43
+ }
44
+ }
45
+ return true;
46
+ }
47
+ /**
48
+ * SQLite vector store.
49
+ *
50
+ * Stores vectors as JSON text columns and loads them into memory for
51
+ * brute-force cosine search. The trade-off is durability with a simple
52
+ * dependency chain — no native extensions beyond `better-sqlite3`.
53
+ */
54
+ export class SqliteVectorStore {
55
+ _db;
56
+ _table;
57
+ _dimensions;
58
+ _initialised = false;
59
+ constructor(config) {
60
+ if (!config.connection) {
61
+ throw new Error("SqliteVectorStore requires a `connection` (better-sqlite3 Database instance).");
62
+ }
63
+ this._db = config.connection;
64
+ this._table = config.tableName ?? "capstan_vectors";
65
+ this._dimensions = config.dimensions;
66
+ }
67
+ // -------------------------------------------------------------------------
68
+ // Schema bootstrap
69
+ // -------------------------------------------------------------------------
70
+ /** @internal */
71
+ _ensureSchema() {
72
+ if (this._initialised)
73
+ return;
74
+ this._db.exec(`
75
+ CREATE TABLE IF NOT EXISTS "${this._esc(this._table)}" (
76
+ id TEXT PRIMARY KEY,
77
+ embedding TEXT NOT NULL,
78
+ content TEXT NOT NULL DEFAULT '',
79
+ metadata TEXT NOT NULL DEFAULT '{}'
80
+ )
81
+ `);
82
+ this._initialised = true;
83
+ }
84
+ // -------------------------------------------------------------------------
85
+ // VectorStore implementation
86
+ // -------------------------------------------------------------------------
87
+ async upsert(id, vector, metadata) {
88
+ this._validateDimensions(vector);
89
+ this._ensureSchema();
90
+ const text = typeof metadata?.["text"] === "string" ? metadata["text"] : "";
91
+ const metaJson = JSON.stringify(metadata ?? {});
92
+ this._db
93
+ .prepare(`INSERT INTO "${this._esc(this._table)}" (id, embedding, content, metadata)
94
+ VALUES (?, ?, ?, ?)
95
+ ON CONFLICT(id) DO UPDATE
96
+ SET embedding = excluded.embedding,
97
+ content = excluded.content,
98
+ metadata = excluded.metadata`)
99
+ .run(id, JSON.stringify(vector), text, metaJson);
100
+ }
101
+ async upsertBatch(items) {
102
+ if (items.length === 0)
103
+ return;
104
+ for (const item of items)
105
+ this._validateDimensions(item.vector);
106
+ this._ensureSchema();
107
+ const stmt = this._db.prepare(`INSERT INTO "${this._esc(this._table)}" (id, embedding, content, metadata)
108
+ VALUES (?, ?, ?, ?)
109
+ ON CONFLICT(id) DO UPDATE
110
+ SET embedding = excluded.embedding,
111
+ content = excluded.content,
112
+ metadata = excluded.metadata`);
113
+ for (const item of items) {
114
+ const text = typeof item.metadata?.["text"] === "string" ? item.metadata["text"] : "";
115
+ const metaJson = JSON.stringify(item.metadata ?? {});
116
+ stmt.run(item.id, JSON.stringify(item.vector), text, metaJson);
117
+ }
118
+ }
119
+ async search(query, k, filter) {
120
+ if (query.length === 0)
121
+ return [];
122
+ this._ensureSchema();
123
+ const rows = this._loadAll();
124
+ const results = [];
125
+ for (const row of rows) {
126
+ if (filter && !matchesFilter(row.metadata, filter))
127
+ continue;
128
+ if (row.vector.length !== query.length)
129
+ continue;
130
+ const score = 1 - cosineDistance(query, row.vector);
131
+ results.push({ id: row.id, score, metadata: row.metadata });
132
+ }
133
+ results.sort((a, b) => b.score - a.score);
134
+ return results.slice(0, Math.max(0, k));
135
+ }
136
+ async hybridSearch(query, queryVector, k, opts) {
137
+ const vectorWeight = opts?.vectorWeight ?? 0.7;
138
+ const keywordWeight = opts?.keywordWeight ?? 0.3;
139
+ const queryTerms = tokenize(query);
140
+ if (queryTerms.length === 0 && queryVector.length === 0)
141
+ return [];
142
+ this._ensureSchema();
143
+ const rows = this._loadAll();
144
+ const results = [];
145
+ for (const row of rows) {
146
+ if (opts?.filter && !matchesFilter(row.metadata, opts.filter))
147
+ continue;
148
+ const vectorScore = queryVector.length > 0 && row.vector.length === queryVector.length
149
+ ? 1 - cosineDistance(queryVector, row.vector)
150
+ : 0;
151
+ const kwScore = keywordOverlap(queryTerms, row.content);
152
+ results.push({
153
+ id: row.id,
154
+ score: vectorWeight * vectorScore + keywordWeight * kwScore,
155
+ metadata: row.metadata,
156
+ });
157
+ }
158
+ results.sort((a, b) => b.score - a.score);
159
+ return results.slice(0, Math.max(0, k));
160
+ }
161
+ async remove(id) {
162
+ this._ensureSchema();
163
+ const result = this._db
164
+ .prepare(`DELETE FROM "${this._esc(this._table)}" WHERE id = ?`)
165
+ .run(id);
166
+ return result.changes > 0;
167
+ }
168
+ async count() {
169
+ this._ensureSchema();
170
+ const row = this._db
171
+ .prepare(`SELECT COUNT(*) AS count FROM "${this._esc(this._table)}"`)
172
+ .get();
173
+ return Number(row?.["count"] ?? 0);
174
+ }
175
+ // -------------------------------------------------------------------------
176
+ // Internal helpers
177
+ // -------------------------------------------------------------------------
178
+ _validateDimensions(vector) {
179
+ if (vector.length === 0) {
180
+ throw new Error("Cannot store a zero-length vector.");
181
+ }
182
+ if (this._dimensions !== undefined && vector.length !== this._dimensions) {
183
+ throw new Error(`Dimension mismatch: expected ${this._dimensions}, got ${vector.length}.`);
184
+ }
185
+ }
186
+ /** Load all stored rows, parsing JSON columns. */
187
+ _loadAll() {
188
+ const rawRows = this._db
189
+ .prepare(`SELECT id, embedding, content, metadata FROM "${this._esc(this._table)}"`)
190
+ .all();
191
+ return rawRows.map((row) => ({
192
+ id: String(row["id"]),
193
+ vector: JSON.parse(String(row["embedding"])),
194
+ content: String(row["content"] ?? ""),
195
+ metadata: JSON.parse(String(row["metadata"] ?? "{}")),
196
+ }));
197
+ }
198
+ /** Escape a SQL identifier (double-quote style). */
199
+ _esc(identifier) {
200
+ return identifier.replace(/"/g, '""');
201
+ }
202
+ }
203
+ //# sourceMappingURL=vector-store-sqlite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vector-store-sqlite.js","sourceRoot":"","sources":["../../../.claude/worktrees/agent-a1ae6f0b/packages/db/src/vector-store-sqlite.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,0EAA0E;AAC1E,8EAA8E;AAC9E,EAAE;AACF,yEAAyE;AACzE,4EAA4E;AAC5E,4EAA4E;AAC5E,qEAAqE;AACrE,EAAE;AACF,8EAA8E;AAC9E,8BAA8B;AAC9B,8EAA8E;AAE9E,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AA+B7C,uEAAuE;AACvE,SAAS,QAAQ,CAAC,IAAY;IAC5B,OAAO;QACL,GAAG,IAAI,GAAG,CACR,IAAI;aACD,WAAW,EAAE;aACb,KAAK,CAAC,KAAK,CAAC;aACZ,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAC/B;KACF,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,UAAoB,EAAE,IAAY;IACxD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACtC,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1C,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,IAAI,EAAE,CAAC;IAClC,CAAC;IACD,OAAO,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC;AAClC,CAAC;AAED,SAAS,aAAa,CAAC,QAAiC,EAAE,MAAoB;IAC5E,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAAE,OAAO,KAAK,CAAC;QAC5C,CAAC;aAAM,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;YAC5B,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,OAAO,iBAAiB;IACX,GAAG,CAAmB;IACtB,MAAM,CAAS;IACf,WAAW,CAAqB;IACzC,YAAY,GAAG,KAAK,CAAC;IAE7B,YAAY,MAA4D;QACtE,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,+EAA+E,CAAC,CAAC;QACnG,CAAC;QACD,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC;QAC7B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,SAAS,IAAI,iBAAiB,CAAC;QACpD,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC;IACvC,CAAC;IAED,4EAA4E;IAC5E,mBAAmB;IACnB,4EAA4E;IAE5E,gBAAgB;IAChB,aAAa;QACX,IAAI,IAAI,CAAC,YAAY;YAAE,OAAO;QAC9B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;oCACkB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;;;;;;KAMrD,CAAC,CAAC;QACH,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;IAC3B,CAAC;IAED,4EAA4E;IAC5E,6BAA6B;IAC7B,4EAA4E;IAE5E,KAAK,CAAC,MAAM,CAAC,EAAU,EAAE,MAAgB,EAAE,QAAkC;QAC3E,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;QACjC,IAAI,CAAC,aAAa,EAAE,CAAC;QAErB,MAAM,IAAI,GAAG,OAAO,QAAQ,EAAE,CAAC,MAAM,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5E,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;QAEhD,IAAI,CAAC,GAAG;aACL,OAAO,CACN,gBAAgB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;;;;;6CAKD,CACtC;aACA,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IACrD,CAAC;IAED,KAAK,CAAC,WAAW,CACf,KAA0F;QAE1F,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAC/B,KAAK,MAAM,IAAI,IAAI,KAAK;YAAE,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAChE,IAAI,CAAC,aAAa,EAAE,CAAC;QAErB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAC3B,gBAAgB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;;;;;2CAKD,CACtC,CAAC;QAEF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACtF,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;YACrD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAe,EAAE,CAAS,EAAE,MAAqB;QAC5D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAClC,IAAI,CAAC,aAAa,EAAE,CAAC;QAErB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAyB,EAAE,CAAC;QAEzC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAAE,SAAS;YAC7D,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM;gBAAE,SAAS;YACjD,MAAM,KAAK,GAAG,CAAC,GAAG,cAAc,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;YACpD,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC9D,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QAC1C,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,YAAY,CAChB,KAAa,EACb,WAAqB,EACrB,CAAS,EACT,IAAgC;QAEhC,MAAM,YAAY,GAAG,IAAI,EAAE,YAAY,IAAI,GAAG,CAAC;QAC/C,MAAM,aAAa,GAAG,IAAI,EAAE,aAAa,IAAI,GAAG,CAAC;QACjD,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;QAEnC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QACnE,IAAI,CAAC,aAAa,EAAE,CAAC;QAErB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAyB,EAAE,CAAC;QAEzC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,IAAI,EAAE,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC;gBAAE,SAAS;YAExE,MAAM,WAAW,GACf,WAAW,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,WAAW,CAAC,MAAM;gBAChE,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC;gBAC7C,CAAC,CAAC,CAAC,CAAC;YAER,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;YAExD,OAAO,CAAC,IAAI,CAAC;gBACX,EAAE,EAAE,GAAG,CAAC,EAAE;gBACV,KAAK,EAAE,YAAY,GAAG,WAAW,GAAG,aAAa,GAAG,OAAO;gBAC3D,QAAQ,EAAE,GAAG,CAAC,QAAQ;aACvB,CAAC,CAAC;QACL,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QAC1C,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAU;QACrB,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG;aACpB,OAAO,CAAC,gBAAgB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC;aAC/D,GAAG,CAAC,EAAE,CAAC,CAAC;QACX,OAAO,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG;aACjB,OAAO,CAAC,kCAAkC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;aACpE,GAAG,EAAE,CAAC;QACT,OAAO,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACrC,CAAC;IAED,4EAA4E;IAC5E,mBAAmB;IACnB,4EAA4E;IAEpE,mBAAmB,CAAC,MAAgB;QAC1C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC;YACzE,MAAM,IAAI,KAAK,CACb,gCAAgC,IAAI,CAAC,WAAW,SAAS,MAAM,CAAC,MAAM,GAAG,CAC1E,CAAC;QACJ,CAAC;IACH,CAAC;IAED,kDAAkD;IAC1C,QAAQ;QACd,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG;aACrB,OAAO,CAAC,iDAAiD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;aACnF,GAAG,EAAE,CAAC;QAET,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YAC3B,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACrB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAa;YACxD,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;YACrC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,CAA4B;SACjF,CAAC,CAAC,CAAC;IACN,CAAC;IAED,oDAAoD;IAC5C,IAAI,CAAC,UAAkB;QAC7B,OAAO,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACxC,CAAC;CACF"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Filter condition for vector search. Each key is a metadata field name and
3
+ * the value is either a literal (exact match) or an array of allowed values.
4
+ */
5
+ export type VectorFilter = Record<string, unknown>;
6
+ /** A single result returned from a vector search operation. */
7
+ export interface VectorSearchResult {
8
+ /** Identifier of the stored vector. */
9
+ id: string;
10
+ /** Similarity score in [0, 1] where 1 is identical. */
11
+ score: number;
12
+ /** Metadata that was stored alongside the vector. */
13
+ metadata?: Record<string, unknown>;
14
+ }
15
+ /** Options for hybrid (keyword + vector) search. */
16
+ export interface VectorHybridSearchOptions {
17
+ /** Weight for the keyword component (0-1). @default 0.3 */
18
+ keywordWeight?: number;
19
+ /** Weight for the vector component (0-1). @default 0.7 */
20
+ vectorWeight?: number;
21
+ /** Optional metadata filter applied before scoring. */
22
+ filter?: VectorFilter;
23
+ }
24
+ /**
25
+ * Pluggable vector storage and similarity search backend.
26
+ *
27
+ * Implementations range from a simple in-memory map (development) through
28
+ * SQLite-backed persistence up to full pgvector-powered ANN search.
29
+ */
30
+ export interface VectorStore {
31
+ /** Insert or update a vector with its ID and optional metadata. */
32
+ upsert(id: string, vector: number[], metadata?: Record<string, unknown>): Promise<void>;
33
+ /** Batch upsert for efficiency. */
34
+ upsertBatch(items: ReadonlyArray<{
35
+ id: string;
36
+ vector: number[];
37
+ metadata?: Record<string, unknown>;
38
+ }>): Promise<void>;
39
+ /** Find k nearest neighbours by vector similarity. */
40
+ search(query: number[], k: number, filter?: VectorFilter): Promise<VectorSearchResult[]>;
41
+ /**
42
+ * Hybrid search combining vector similarity with keyword text matching.
43
+ *
44
+ * The `query` string is used for keyword scoring while `queryVector` drives
45
+ * the vector similarity component.
46
+ */
47
+ hybridSearch(query: string, queryVector: number[], k: number, opts?: VectorHybridSearchOptions): Promise<VectorSearchResult[]>;
48
+ /** Remove a vector by ID. Returns `true` if the entry existed. */
49
+ remove(id: string): Promise<boolean>;
50
+ /** Return the number of stored vectors. */
51
+ count(): Promise<number>;
52
+ }
53
+ /** Configuration accepted by the {@link createVectorStore} factory. */
54
+ export interface VectorStoreConfig {
55
+ /** Backend provider to use. */
56
+ provider: "memory" | "pgvector" | "sqlite";
57
+ /**
58
+ * Number of dimensions each vector contains. Required for pgvector so that
59
+ * the column can be sized correctly; optional for memory and SQLite stores.
60
+ */
61
+ dimensions?: number;
62
+ /**
63
+ * Name of the database table used for persistence.
64
+ * @default "capstan_vectors"
65
+ */
66
+ tableName?: string;
67
+ /**
68
+ * A raw query function used by the pgvector and SQLite adapters.
69
+ *
70
+ * For pgvector this should be a function that accepts a parameterised SQL
71
+ * string with `$1`, `$2`, etc. placeholders and returns an array of row
72
+ * objects.
73
+ *
74
+ * For SQLite this should be a synchronous `better-sqlite3` `Database`
75
+ * instance (it will be accessed via `.prepare().all()` / `.run()`).
76
+ */
77
+ connection?: unknown;
78
+ }
79
+ //# sourceMappingURL=vector-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vector-store.d.ts","sourceRoot":"","sources":["../../../.claude/worktrees/agent-a1ae6f0b/packages/db/src/vector-store.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEnD,+DAA+D;AAC/D,MAAM,WAAW,kBAAkB;IACjC,uCAAuC;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,oDAAoD;AACpD,MAAM,WAAW,yBAAyB;IACxC,2DAA2D;IAC3D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uDAAuD;IACvD,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,mEAAmE;IACnE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExF,mCAAmC;IACnC,WAAW,CAAC,KAAK,EAAE,aAAa,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvH,sDAAsD;IACtD,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAEzF;;;;;OAKG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,yBAAyB,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAE/H,mEAAmE;IACnE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAErC,2CAA2C;IAC3C,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1B;AAED,uEAAuE;AACvE,MAAM,WAAW,iBAAiB;IAChC,+BAA+B;IAC/B,QAAQ,EAAE,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC;IAE3C;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB"}
@@ -0,0 +1,5 @@
1
+ // ---------------------------------------------------------------------------
2
+ // VectorStore — adapter interface for pluggable vector search backends
3
+ // ---------------------------------------------------------------------------
4
+ export {};
5
+ //# sourceMappingURL=vector-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vector-store.js","sourceRoot":"","sources":["../../../.claude/worktrees/agent-a1ae6f0b/packages/db/src/vector-store.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,uEAAuE;AACvE,8EAA8E"}
@@ -0,0 +1,15 @@
1
+ import type { EmbeddingConfig } from "./embedding.js";
2
+ import type { ModelDefinition } from "./types.js";
3
+ export interface PrepareWriteOptions {
4
+ now?: Date;
5
+ embeddings?: Array<EmbeddingConfig & {
6
+ modelName?: string;
7
+ }> | (EmbeddingConfig & {
8
+ modelName?: string;
9
+ });
10
+ }
11
+ type RecordInput = Record<string, unknown>;
12
+ export declare function prepareCreateData(model: ModelDefinition, input: RecordInput, options?: PrepareWriteOptions): Promise<RecordInput>;
13
+ export declare function prepareUpdateData(model: ModelDefinition, input: RecordInput, options?: PrepareWriteOptions): Promise<RecordInput>;
14
+ export {};
15
+ //# sourceMappingURL=write.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../src/write.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtD,OAAO,KAAK,EAAmB,eAAe,EAAE,MAAM,YAAY,CAAC;AAEnE,MAAM,WAAW,mBAAmB;IAClC,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,UAAU,CAAC,EAAE,KAAK,CAAC,eAAe,GAAG;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,CAAC,eAAe,GAAG;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC3G;AAED,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AA4L3C,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,eAAe,EACtB,KAAK,EAAE,WAAW,EAClB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,WAAW,CAAC,CAEtB;AAED,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,eAAe,EACtB,KAAK,EAAE,WAAW,EAClB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,WAAW,CAAC,CAEtB"}
package/dist/write.js ADDED
@@ -0,0 +1,156 @@
1
+ import { cloneDefaultValue } from "./naming.js";
2
+ function assertKnownFields(model, input) {
3
+ for (const key of Object.keys(input)) {
4
+ if (!(key in model.fields)) {
5
+ throw new Error(`Unknown field "${key}" for model "${model.name}".`);
6
+ }
7
+ }
8
+ }
9
+ function validateFieldValue(model, fieldName, field, value) {
10
+ if (value === undefined)
11
+ return;
12
+ if (value === null) {
13
+ if (field.required || field.updatedAt || field.autoId) {
14
+ throw new Error(`Field "${model.name}.${fieldName}" cannot be null.`);
15
+ }
16
+ return;
17
+ }
18
+ switch (field.type) {
19
+ case "string":
20
+ case "text":
21
+ if (typeof value !== "string") {
22
+ throw new Error(`Field "${model.name}.${fieldName}" must be a string.`);
23
+ }
24
+ if (field.min !== undefined && value.length < field.min) {
25
+ throw new Error(`Field "${model.name}.${fieldName}" must be at least ${field.min} characters.`);
26
+ }
27
+ if (field.max !== undefined && value.length > field.max) {
28
+ throw new Error(`Field "${model.name}.${fieldName}" must be at most ${field.max} characters.`);
29
+ }
30
+ break;
31
+ case "date":
32
+ if (typeof value !== "string" || !/^\d{4}-\d{2}-\d{2}$/.test(value)) {
33
+ throw new Error(`Field "${model.name}.${fieldName}" must be a YYYY-MM-DD string.`);
34
+ }
35
+ break;
36
+ case "datetime":
37
+ if (typeof value !== "string" || Number.isNaN(Date.parse(value))) {
38
+ throw new Error(`Field "${model.name}.${fieldName}" must be a valid datetime string.`);
39
+ }
40
+ break;
41
+ case "integer":
42
+ if (typeof value !== "number" || !Number.isInteger(value)) {
43
+ throw new Error(`Field "${model.name}.${fieldName}" must be an integer.`);
44
+ }
45
+ if (field.min !== undefined && value < field.min) {
46
+ throw new Error(`Field "${model.name}.${fieldName}" must be at least ${field.min}.`);
47
+ }
48
+ if (field.max !== undefined && value > field.max) {
49
+ throw new Error(`Field "${model.name}.${fieldName}" must be at most ${field.max}.`);
50
+ }
51
+ break;
52
+ case "number":
53
+ if (typeof value !== "number" || Number.isNaN(value)) {
54
+ throw new Error(`Field "${model.name}.${fieldName}" must be a number.`);
55
+ }
56
+ if (field.min !== undefined && value < field.min) {
57
+ throw new Error(`Field "${model.name}.${fieldName}" must be at least ${field.min}.`);
58
+ }
59
+ if (field.max !== undefined && value > field.max) {
60
+ throw new Error(`Field "${model.name}.${fieldName}" must be at most ${field.max}.`);
61
+ }
62
+ break;
63
+ case "boolean":
64
+ if (typeof value !== "boolean") {
65
+ throw new Error(`Field "${model.name}.${fieldName}" must be a boolean.`);
66
+ }
67
+ break;
68
+ case "vector":
69
+ if (!Array.isArray(value) || value.some((entry) => typeof entry !== "number" || Number.isNaN(entry))) {
70
+ throw new Error(`Field "${model.name}.${fieldName}" must be a numeric vector.`);
71
+ }
72
+ if (field.dimensions !== undefined && value.length !== field.dimensions) {
73
+ throw new Error(`Field "${model.name}.${fieldName}" must contain exactly ${field.dimensions} dimensions.`);
74
+ }
75
+ break;
76
+ case "json":
77
+ break;
78
+ }
79
+ if (field.enum && !field.enum.includes(value)) {
80
+ throw new Error(`Field "${model.name}.${fieldName}" must be one of: ${field.enum.join(", ")}.`);
81
+ }
82
+ }
83
+ function validateRequiredFields(model, payload) {
84
+ for (const [fieldName, field] of Object.entries(model.fields)) {
85
+ if ((field.required || field.updatedAt || field.autoId) && payload[fieldName] === undefined) {
86
+ throw new Error(`Missing required field "${model.name}.${fieldName}".`);
87
+ }
88
+ }
89
+ }
90
+ function nowValue(field, now) {
91
+ switch (field.type) {
92
+ case "date":
93
+ return now.toISOString().slice(0, 10);
94
+ case "datetime":
95
+ return now.toISOString();
96
+ default:
97
+ return now.toISOString();
98
+ }
99
+ }
100
+ function embeddingConfigsForModel(model, embeddings) {
101
+ const list = embeddings === undefined ? [] : Array.isArray(embeddings) ? embeddings : [embeddings];
102
+ return list.filter((config) => config.modelName === undefined || config.modelName === model.name);
103
+ }
104
+ async function applyEmbeddings(model, payload, embeddings) {
105
+ for (const config of embeddingConfigsForModel(model, embeddings)) {
106
+ const sourceValue = payload[config.sourceField];
107
+ if (sourceValue === undefined || sourceValue === null)
108
+ continue;
109
+ if (typeof sourceValue !== "string") {
110
+ throw new Error(`Embedding source field "${config.sourceField}" on model "${model.name}" must resolve to a string.`);
111
+ }
112
+ const vectors = await config.adapter.embed([sourceValue]);
113
+ const vector = vectors[0];
114
+ if (!vector) {
115
+ throw new Error(`Embedding adapter for model "${model.name}" returned no embedding for "${config.sourceField}".`);
116
+ }
117
+ const vectorField = model.fields[config.vectorField];
118
+ if (vectorField?.dimensions !== undefined && vector.length !== vectorField.dimensions) {
119
+ throw new Error(`Embedding dimensions mismatch for "${model.name}.${config.vectorField}": expected ${vectorField.dimensions}, received ${vector.length}.`);
120
+ }
121
+ payload[config.vectorField] = vector;
122
+ }
123
+ }
124
+ async function prepareWrite(mode, model, input, options) {
125
+ const now = options?.now ?? new Date();
126
+ const payload = { ...input };
127
+ assertKnownFields(model, payload);
128
+ for (const [fieldName, field] of Object.entries(model.fields)) {
129
+ if (mode === "create") {
130
+ if (field.autoId && payload[fieldName] === undefined) {
131
+ payload[fieldName] = globalThis.crypto.randomUUID();
132
+ }
133
+ if (payload[fieldName] === undefined && field.default !== undefined) {
134
+ payload[fieldName] = field.default === "now" ? nowValue(field, now) : cloneDefaultValue(field.default);
135
+ }
136
+ }
137
+ if (field.updatedAt) {
138
+ payload[fieldName] = nowValue(field, now);
139
+ }
140
+ }
141
+ await applyEmbeddings(model, payload, options?.embeddings);
142
+ if (mode === "create") {
143
+ validateRequiredFields(model, payload);
144
+ }
145
+ for (const [fieldName, field] of Object.entries(model.fields)) {
146
+ validateFieldValue(model, fieldName, field, payload[fieldName]);
147
+ }
148
+ return payload;
149
+ }
150
+ export async function prepareCreateData(model, input, options) {
151
+ return prepareWrite("create", model, input, options);
152
+ }
153
+ export async function prepareUpdateData(model, input, options) {
154
+ return prepareWrite("update", model, input, options);
155
+ }
156
+ //# sourceMappingURL=write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write.js","sourceRoot":"","sources":["../src/write.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zauso-ai/capstan-db",
3
- "version": "0.1.4",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -12,11 +12,15 @@
12
12
  },
13
13
  "scripts": {
14
14
  "build": "tsc -p tsconfig.json",
15
- "typecheck": "tsc -p tsconfig.json --noEmit"
15
+ "typecheck": "tsc -p tsconfig.json --noEmit",
16
+ "clean": "rm -rf dist"
16
17
  },
17
18
  "peerDependencies": {
18
- "drizzle-orm": "^0.44.0",
19
- "better-sqlite3": "^11.0.0"
19
+ "drizzle-orm": ">=0.44.0",
20
+ "better-sqlite3": ">=9.0.0",
21
+ "@libsql/client": ">=0.15.0",
22
+ "pg": "^8.0.0",
23
+ "mysql2": "^3.0.0"
20
24
  },
21
25
  "peerDependenciesMeta": {
22
26
  "drizzle-orm": {
@@ -24,6 +28,15 @@
24
28
  },
25
29
  "better-sqlite3": {
26
30
  "optional": true
31
+ },
32
+ "@libsql/client": {
33
+ "optional": true
34
+ },
35
+ "pg": {
36
+ "optional": true
37
+ },
38
+ "mysql2": {
39
+ "optional": true
27
40
  }
28
41
  },
29
42
  "description": "Database layer for Capstan — Drizzle ORM, defineModel, auto CRUD generation",