@j0hanz/memdb 1.2.6 → 1.2.9

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 (54) hide show
  1. package/dist/config.d.ts +2 -0
  2. package/dist/config.d.ts.map +1 -0
  3. package/dist/config.js +15 -0
  4. package/dist/config.js.map +1 -0
  5. package/dist/core/db.d.ts +5 -3
  6. package/dist/core/db.d.ts.map +1 -0
  7. package/dist/core/db.js +52 -52
  8. package/dist/core/db.js.map +1 -0
  9. package/dist/core/memory-read.d.ts +1 -0
  10. package/dist/core/memory-read.d.ts.map +1 -0
  11. package/dist/core/memory-read.js +8 -7
  12. package/dist/core/memory-read.js.map +1 -0
  13. package/dist/core/memory-write.d.ts +1 -0
  14. package/dist/core/memory-write.d.ts.map +1 -0
  15. package/dist/core/memory-write.js +15 -30
  16. package/dist/core/memory-write.js.map +1 -0
  17. package/dist/core/relationships.d.ts +1 -0
  18. package/dist/core/relationships.d.ts.map +1 -0
  19. package/dist/core/relationships.js +15 -19
  20. package/dist/core/relationships.js.map +1 -0
  21. package/dist/core/search.d.ts +3 -2
  22. package/dist/core/search.d.ts.map +1 -0
  23. package/dist/core/search.js +36 -12
  24. package/dist/core/search.js.map +1 -0
  25. package/dist/index.d.ts +1 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +39 -33
  28. package/dist/index.js.map +1 -0
  29. package/dist/instructions.md +34 -159
  30. package/dist/logger.d.ts +5 -0
  31. package/dist/logger.d.ts.map +1 -0
  32. package/dist/logger.js +19 -0
  33. package/dist/logger.js.map +1 -0
  34. package/dist/protocol-version-guard.d.ts +1 -0
  35. package/dist/protocol-version-guard.d.ts.map +1 -0
  36. package/dist/protocol-version-guard.js +11 -1
  37. package/dist/protocol-version-guard.js.map +1 -0
  38. package/dist/schemas.d.ts +1 -0
  39. package/dist/schemas.d.ts.map +1 -0
  40. package/dist/schemas.js +6 -5
  41. package/dist/schemas.js.map +1 -0
  42. package/dist/stdio-transport.d.ts +1 -0
  43. package/dist/stdio-transport.d.ts.map +1 -0
  44. package/dist/stdio-transport.js +2 -3
  45. package/dist/stdio-transport.js.map +1 -0
  46. package/dist/tools.d.ts +15 -23
  47. package/dist/tools.d.ts.map +1 -0
  48. package/dist/tools.js +44 -18
  49. package/dist/tools.js.map +1 -0
  50. package/dist/types.d.ts +1 -0
  51. package/dist/types.d.ts.map +1 -0
  52. package/dist/types.js +1 -0
  53. package/dist/types.js.map +1 -0
  54. package/package.json +14 -10
package/dist/config.d.ts CHANGED
@@ -2,5 +2,7 @@ type LogLevel = 'error' | 'info' | 'warn';
2
2
  export declare const config: {
3
3
  dbPath: string;
4
4
  logLevel: LogLevel;
5
+ toolTimeoutMs: number;
5
6
  };
6
7
  export {};
8
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,KAAK,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAoD1C,eAAO,MAAM,MAAM;;;;CAQlB,CAAC"}
package/dist/config.js CHANGED
@@ -2,6 +2,7 @@ import path from 'node:path';
2
2
  import process from 'node:process';
3
3
  const DEFAULT_DB_PATH = path.join(process.cwd(), '.memdb', 'memory.db');
4
4
  const DEFAULT_LOG_LEVEL = 'info';
5
+ const DEFAULT_TOOL_TIMEOUT_MS = 15000;
5
6
  const hasNullByte = (value) => value.includes('\0');
6
7
  const parseLogLevel = (value) => {
7
8
  if (value === undefined)
@@ -18,6 +19,18 @@ const parseLogLevel = (value) => {
18
19
  throw new Error(`Invalid MEMDB_LOG_LEVEL: ${value} (expected: error|warn|info)`);
19
20
  }
20
21
  };
22
+ const parseTimeoutMs = (value, name) => {
23
+ if (value === undefined)
24
+ return undefined;
25
+ if (hasNullByte(value)) {
26
+ throw new Error(`Invalid ${name}: null byte detected`);
27
+ }
28
+ const parsed = Number(value);
29
+ if (!Number.isFinite(parsed) || parsed < 0 || !Number.isInteger(parsed)) {
30
+ throw new Error(`Invalid ${name}: expected a non-negative integer`);
31
+ }
32
+ return parsed;
33
+ };
21
34
  const resolveDbPath = (env) => {
22
35
  const envPath = env.MEMDB_PATH;
23
36
  if (envPath !== undefined) {
@@ -34,4 +47,6 @@ const resolveDbPath = (env) => {
34
47
  export const config = {
35
48
  dbPath: resolveDbPath(process.env),
36
49
  logLevel: parseLogLevel(process.env.MEMDB_LOG_LEVEL) ?? DEFAULT_LOG_LEVEL,
50
+ toolTimeoutMs: parseTimeoutMs(process.env.MEMDB_TOOL_TIMEOUT_MS, 'MEMDB_TOOL_TIMEOUT_MS') ?? DEFAULT_TOOL_TIMEOUT_MS,
37
51
  };
52
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,OAAO,MAAM,cAAc,CAAC;AAInC,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;AACxE,MAAM,iBAAiB,GAAa,MAAM,CAAC;AAC3C,MAAM,uBAAuB,GAAG,KAAK,CAAC;AAEtC,MAAM,WAAW,GAAG,CAAC,KAAa,EAAW,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAErE,MAAM,aAAa,GAAG,CAAC,KAAyB,EAAwB,EAAE;IACxE,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,IAAI,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACjE,CAAC;IACD,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,OAAO,CAAC;QACb,KAAK,MAAM,CAAC;QACZ,KAAK,MAAM;YACT,OAAO,KAAK,CAAC;QACf;YACE,MAAM,IAAI,KAAK,CACb,4BAA4B,KAAK,8BAA8B,CAChE,CAAC;IACN,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CACrB,KAAyB,EACzB,IAAY,EACQ,EAAE;IACtB,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,IAAI,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,sBAAsB,CAAC,CAAC;IACzD,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;QACxE,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,mCAAmC,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,GAAsB,EAAU,EAAE;IACvD,MAAM,OAAO,GAAG,GAAG,CAAC,UAAU,CAAC;IAC/B,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,IAAI,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC5D,CAAC;QACD,IAAI,OAAO,KAAK,UAAU;YAAE,OAAO,UAAU,CAAC;QAC9C,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;AACvC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,MAAM,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC;IAClC,QAAQ,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,iBAAiB;IACzE,aAAa,EACX,cAAc,CACZ,OAAO,CAAC,GAAG,CAAC,qBAAqB,EACjC,uBAAuB,CACxB,IAAI,uBAAuB;CAC/B,CAAC"}
package/dist/core/db.d.ts CHANGED
@@ -1,12 +1,13 @@
1
1
  import { DatabaseSync, type StatementSync } from 'node:sqlite';
2
2
  import { type Memory, type Relationship, type SearchResult } from '../types.js';
3
3
  export type DbRow = Record<string, unknown>;
4
- export declare const db: DatabaseSync;
4
+ export declare const initDb: () => Promise<void>;
5
+ export declare const getDb: () => DatabaseSync;
5
6
  export declare const closeDb: () => void;
6
7
  export type SqlParam = string | number | bigint | null | Uint8Array;
7
8
  export declare const prepareCached: (sql: string) => StatementSync;
8
- export declare const executeAll: (stmt: StatementSync, ...params: SqlParam[]) => DbRow[];
9
- export declare const executeGet: (stmt: StatementSync, ...params: SqlParam[]) => DbRow | undefined;
9
+ export declare const executeAll: <T = DbRow>(stmt: StatementSync, ...params: SqlParam[]) => T[];
10
+ export declare const executeGet: <T = DbRow>(stmt: StatementSync, ...params: SqlParam[]) => T | undefined;
10
11
  export declare const executeRun: (stmt: StatementSync, ...params: SqlParam[]) => {
11
12
  changes: number | bigint;
12
13
  };
@@ -16,3 +17,4 @@ export declare const mapRowToMemory: (row: DbRow, tags?: string[]) => Memory;
16
17
  export declare const mapRowToSearchResult: (row: DbRow, tags?: string[]) => SearchResult;
17
18
  export declare const mapRowToRelationship: (row: DbRow) => Relationship;
18
19
  export declare const loadTagsForMemoryIds: (memoryIds: readonly number[]) => Map<number, string[]>;
20
+ //# sourceMappingURL=db.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/core/db.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAG/D,OAAO,EACL,KAAK,MAAM,EAGX,KAAK,YAAY,EACjB,KAAK,YAAY,EAClB,MAAM,aAAa,CAAC;AAErB,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AA8H5C,eAAO,MAAM,MAAM,QAAa,OAAO,CAAC,IAAI,CAW3C,CAAC;AAEF,eAAO,MAAM,KAAK,QAAO,YAKxB,CAAC;AAEF,eAAO,MAAM,OAAO,QAAO,IAM1B,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,UAAU,CAAC;AAKpE,eAAO,MAAM,aAAa,GAAI,KAAK,MAAM,KAAG,aAiB3C,CAAC;AAqCF,eAAO,MAAM,UAAU,GAAI,CAAC,GAAG,KAAK,EAClC,MAAM,aAAa,EACnB,GAAG,QAAQ,QAAQ,EAAE,KACpB,CAAC,EAA8C,CAAC;AAGnD,eAAO,MAAM,UAAU,GAAI,CAAC,GAAG,KAAK,EAClC,MAAM,aAAa,EACnB,GAAG,QAAQ,QAAQ,EAAE,KACpB,CAAC,GAAG,SAAqE,CAAC;AAE7E,eAAO,MAAM,UAAU,GACrB,MAAM,aAAa,EACnB,GAAG,QAAQ,QAAQ,EAAE,KACpB;IAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAAA;CAAsC,CAAC;AAEpE,eAAO,MAAM,wBAAwB,GAAI,CAAC,EAAE,WAAW,MAAM,CAAC,KAAG,CAchE,CAAC;AAsBF,eAAO,MAAM,aAAa,GAAI,OAAO,OAAO,EAAE,OAAO,MAAM,KAAG,MAM7D,CAAC;AAkCF,eAAO,MAAM,cAAc,GAAI,KAAK,KAAK,EAAE,OAAM,MAAM,EAAO,KAAG,MAU/D,CAAC;AAEH,eAAO,MAAM,oBAAoB,GAC/B,KAAK,KAAK,EACV,OAAM,MAAM,EAAO,KAClB,YAGD,CAAC;AAEH,eAAO,MAAM,oBAAoB,GAAI,KAAK,KAAK,KAAG,YAMhD,CAAC;AAsBH,eAAO,MAAM,oBAAoB,GAC/B,WAAW,SAAS,MAAM,EAAE,KAC3B,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAgBtB,CAAC"}
package/dist/core/db.js CHANGED
@@ -86,18 +86,14 @@ const ensureDbDirectory = async (dbPath) => {
86
86
  return;
87
87
  await withTimeout(mkdir(path.dirname(dbPath), { recursive: true }), 5000, 'Database directory creation timed out');
88
88
  };
89
- const isEnableDefensive = (value) => {
90
- return typeof value === 'function';
91
- };
92
89
  const enableDefensiveMode = (database) => {
93
- const enableDefensive = Reflect.get(database, 'enableDefensive');
94
- if (!isEnableDefensive(enableDefensive))
95
- return;
96
- enableDefensive(true);
90
+ const extended = database;
91
+ if (typeof extended.enableDefensive === 'function') {
92
+ extended.enableDefensive(true);
93
+ }
97
94
  };
98
95
  const isInTransaction = (database) => {
99
- const prop = Reflect.get(database, 'isTransaction');
100
- return typeof prop === 'boolean' ? prop : false;
96
+ return database.isTransaction;
101
97
  };
102
98
  const initializeSchema = (database) => {
103
99
  database.exec(SCHEMA_SQL);
@@ -113,30 +109,50 @@ const createDatabase = (dbPath) => {
113
109
  initializeSchema(database);
114
110
  return database;
115
111
  };
116
- try {
117
- await ensureDbDirectory(config.dbPath);
118
- }
119
- catch (err) {
120
- const message = err instanceof Error ? err.message : String(err);
121
- console.error(`[ERROR] Failed to create database directory: ${message}`);
122
- throw err;
123
- }
124
- export const db = createDatabase(config.dbPath);
125
- export const closeDb = () => {
126
- if (!db.isOpen)
112
+ let dbInstance;
113
+ export const initDb = async () => {
114
+ if (dbInstance)
127
115
  return;
128
- db.close();
116
+ try {
117
+ await ensureDbDirectory(config.dbPath);
118
+ dbInstance = createDatabase(config.dbPath);
119
+ }
120
+ catch (err) {
121
+ const message = err instanceof Error ? err.message : String(err);
122
+ console.error(`[ERROR] Failed to initialize database: ${message}`);
123
+ throw err;
124
+ }
125
+ };
126
+ export const getDb = () => {
127
+ if (!dbInstance) {
128
+ throw new Error('Database not initialized. Call initDb() first.');
129
+ }
130
+ return dbInstance;
131
+ };
132
+ export const closeDb = () => {
133
+ if (dbInstance?.isOpen) {
134
+ dbInstance.close();
135
+ dbInstance = undefined;
136
+ statementCache.clear();
137
+ }
129
138
  };
130
139
  const MAX_CACHED_STATEMENTS = 200;
131
140
  const statementCache = new Map();
132
- const statementCacheOrder = [];
133
- const enforceStatementCacheLimit = () => {
134
- if (statementCacheOrder.length <= MAX_CACHED_STATEMENTS)
135
- return;
136
- const oldestSql = statementCacheOrder.shift();
137
- if (!oldestSql)
138
- return;
139
- statementCache.delete(oldestSql);
141
+ export const prepareCached = (sql) => {
142
+ const cached = statementCache.get(sql);
143
+ if (cached) {
144
+ statementCache.delete(sql);
145
+ statementCache.set(sql, cached);
146
+ return cached;
147
+ }
148
+ const stmt = getDb().prepare(sql);
149
+ statementCache.set(sql, stmt);
150
+ if (statementCache.size > MAX_CACHED_STATEMENTS) {
151
+ const oldestKey = statementCache.keys().next().value;
152
+ if (oldestKey)
153
+ statementCache.delete(oldestKey);
154
+ }
155
+ return stmt;
140
156
  };
141
157
  const isDbRow = (value) => {
142
158
  return typeof value === 'object' && value !== null;
@@ -162,26 +178,19 @@ const toRunResult = (value) => {
162
178
  if (typeof value !== 'object' || value === null) {
163
179
  throw new Error('Invalid run result');
164
180
  }
165
- const changes = Reflect.get(value, 'changes');
181
+ const result = value;
182
+ const { changes } = result;
166
183
  if (typeof changes !== 'number' && typeof changes !== 'bigint') {
167
184
  throw new Error('Invalid run result');
168
185
  }
169
186
  return { changes };
170
187
  };
171
- export const prepareCached = (sql) => {
172
- const cached = statementCache.get(sql);
173
- if (cached)
174
- return cached;
175
- const stmt = db.prepare(sql);
176
- statementCache.set(sql, stmt);
177
- statementCacheOrder.push(sql);
178
- enforceStatementCacheLimit();
179
- return stmt;
180
- };
181
188
  export const executeAll = (stmt, ...params) => toDbRowArray(stmt.all(...params));
189
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
182
190
  export const executeGet = (stmt, ...params) => toDbRowOrUndefined(stmt.get(...params));
183
191
  export const executeRun = (stmt, ...params) => toRunResult(stmt.run(...params));
184
192
  export const withImmediateTransaction = (operation) => {
193
+ const db = getDb();
185
194
  if (isInTransaction(db)) {
186
195
  throw new Error('Cannot start nested transaction');
187
196
  }
@@ -264,16 +273,6 @@ export const mapRowToRelationship = (row) => ({
264
273
  relation_type: toString(row.relation_type, 'relation_type'),
265
274
  created_at: toString(row.created_at, 'created_at'),
266
275
  });
267
- const tagsSelectStatements = [];
268
- const getSelectTagsStatement = (idCount) => {
269
- const cached = tagsSelectStatements[idCount];
270
- if (cached)
271
- return cached;
272
- const placeholders = Array.from({ length: idCount }, () => '?').join(', ');
273
- const stmt = db.prepare(`SELECT memory_id, tag FROM tags WHERE memory_id IN (${placeholders}) ORDER BY memory_id, tag`);
274
- tagsSelectStatements[idCount] = stmt;
275
- return stmt;
276
- };
277
276
  const dedupeIds = (ids) => {
278
277
  const seen = new Set();
279
278
  const unique = [];
@@ -297,8 +296,8 @@ export const loadTagsForMemoryIds = (memoryIds) => {
297
296
  const uniqueIds = dedupeIds(memoryIds);
298
297
  if (uniqueIds.length === 0)
299
298
  return new Map();
300
- const stmt = getSelectTagsStatement(uniqueIds.length);
301
- const rows = executeAll(stmt, ...uniqueIds);
299
+ const stmtSelectTags = prepareCached('SELECT memory_id, tag FROM tags WHERE memory_id IN (SELECT value FROM json_each(?)) ORDER BY memory_id, tag');
300
+ const rows = executeAll(stmtSelectTags, JSON.stringify(uniqueIds));
302
301
  const tagsById = new Map();
303
302
  for (const row of rows) {
304
303
  const memoryId = toSafeInteger(row.memory_id, 'memory_id');
@@ -307,3 +306,4 @@ export const loadTagsForMemoryIds = (memoryIds) => {
307
306
  }
308
307
  return tagsById;
309
308
  };
309
+ //# sourceMappingURL=db.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/core/db.ts"],"names":[],"mappings":"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"}
@@ -3,3 +3,4 @@ export declare const getMemory: (hash: string) => Memory | undefined;
3
3
  export declare const deleteMemory: (hash: string) => StatementResult;
4
4
  export declare const deleteMemories: (hashes: string[]) => BatchDeleteResult;
5
5
  export declare const getStats: () => MemoryStats;
6
+ //# sourceMappingURL=memory-read.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-read.d.ts","sourceRoot":"","sources":["../../src/core/memory-read.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,iBAAiB,EACjB,MAAM,EACN,WAAW,EACX,eAAe,EAChB,MAAM,aAAa,CAAC;AAYrB,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,KAAG,MAAM,GAAG,SAiBjD,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,KAAG,eAM3C,CAAC;AAoBF,eAAO,MAAM,cAAc,GAAI,QAAQ,MAAM,EAAE,KAAG,iBAejD,CAAC;AA4BF,eAAO,MAAM,QAAQ,QAAO,WAc3B,CAAC"}
@@ -1,10 +1,9 @@
1
- import { db, executeGet, executeRun, loadTagsForMemoryIds, mapRowToMemory, toSafeInteger, withImmediateTransaction, } from './db.js';
2
- const stmtGetMemoryByHash = db.prepare('SELECT * FROM memories WHERE hash = ?');
3
- const stmtTouchMemoryByHash = db.prepare('UPDATE memories SET accessed_at = CURRENT_TIMESTAMP WHERE hash = ?');
4
- const stmtDeleteMemoryByHash = db.prepare('DELETE FROM memories WHERE hash = ?');
1
+ import { executeGet, executeRun, loadTagsForMemoryIds, mapRowToMemory, prepareCached, toSafeInteger, withImmediateTransaction, } from './db.js';
5
2
  export const getMemory = (hash) => {
6
3
  return withImmediateTransaction(() => {
4
+ const stmtTouchMemoryByHash = prepareCached('UPDATE memories SET accessed_at = CURRENT_TIMESTAMP WHERE hash = ?');
7
5
  executeRun(stmtTouchMemoryByHash, hash);
6
+ const stmtGetMemoryByHash = prepareCached('SELECT * FROM memories WHERE hash = ?');
8
7
  const row = executeGet(stmtGetMemoryByHash, hash);
9
8
  if (!row)
10
9
  return undefined;
@@ -14,6 +13,7 @@ export const getMemory = (hash) => {
14
13
  });
15
14
  };
16
15
  export const deleteMemory = (hash) => {
16
+ const stmtDeleteMemoryByHash = prepareCached('DELETE FROM memories WHERE hash = ?');
17
17
  const result = executeRun(stmtDeleteMemoryByHash, hash);
18
18
  return { changes: toSafeInteger(result.changes, 'changes') };
19
19
  };
@@ -47,9 +47,6 @@ export const deleteMemories = (hashes) => {
47
47
  return { results, succeeded, failed };
48
48
  });
49
49
  };
50
- const stmtMemoryCount = db.prepare('SELECT COUNT(*) as count FROM memories');
51
- const stmtTagCount = db.prepare('SELECT COUNT(DISTINCT tag) as count FROM tags');
52
- const stmtDateRange = db.prepare('SELECT MIN(created_at) as oldest, MAX(created_at) as newest FROM memories');
53
50
  const toDateString = (value) => {
54
51
  if (value == null)
55
52
  return null;
@@ -60,7 +57,9 @@ const toDateString = (value) => {
60
57
  return null;
61
58
  };
62
59
  const queryCounts = () => {
60
+ const stmtMemoryCount = prepareCached('SELECT COUNT(*) as count FROM memories');
63
61
  const memoryRow = executeGet(stmtMemoryCount);
62
+ const stmtTagCount = prepareCached('SELECT COUNT(DISTINCT tag) as count FROM tags');
64
63
  const tagRow = executeGet(stmtTagCount);
65
64
  if (!memoryRow)
66
65
  throw new Error('Failed to load memory stats');
@@ -70,6 +69,7 @@ const queryCounts = () => {
70
69
  };
71
70
  export const getStats = () => {
72
71
  const { memoryRow, tagRow } = queryCounts();
72
+ const stmtDateRange = prepareCached('SELECT MIN(created_at) as oldest, MAX(created_at) as newest FROM memories');
73
73
  const dateRow = executeGet(stmtDateRange);
74
74
  return {
75
75
  memoryCount: toSafeInteger(memoryRow.count, 'memoryCount'),
@@ -78,3 +78,4 @@ export const getStats = () => {
78
78
  newestMemory: toDateString(dateRow?.newest),
79
79
  };
80
80
  };
81
+ //# sourceMappingURL=memory-read.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-read.js","sourceRoot":"","sources":["../../src/core/memory-read.ts"],"names":[],"mappings":"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"}
@@ -17,3 +17,4 @@ interface UpdateMemoryOptions {
17
17
  }
18
18
  export declare const updateMemory: (hash: string, options: UpdateMemoryOptions) => MemoryUpdateResult;
19
19
  export {};
20
+ //# sourceMappingURL=memory-write.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-write.d.ts","sourceRoot":"","sources":["../../src/core/memory-write.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,gBAAgB,EAChB,kBAAkB,EAClB,UAAU,EACV,kBAAkB,EACnB,MAAM,aAAa,CAAC;AAiGrB,eAAO,MAAM,YAAY,GAAI,OAAO;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,UAAU,CAAC;CAC1B,KAAG,kBAC8D,CAAC;AAqBnE,eAAO,MAAM,cAAc,GACzB,OAAO;IACL,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,UAAU,CAAC;CAC1B,EAAE,KACF,gBAEF,CAAC;AAqEF,UAAU,mBAAmB;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;CACtC;AAkBD,eAAO,MAAM,YAAY,GACvB,MAAM,MAAM,EACZ,SAAS,mBAAmB,KAC3B,kBAuBF,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import crypto from 'node:crypto';
2
- import { db, executeGet, executeRun, toSafeInteger, withImmediateTransaction, } from './db.js';
2
+ import { executeGet, executeRun, prepareCached, toSafeInteger, withImmediateTransaction, } from './db.js';
3
3
  const MAX_TAGS = 100;
4
4
  const TAG_PATTERN = /^\S+$/;
5
5
  const validateTag = (tag) => {
@@ -32,22 +32,8 @@ const normalizeTags = (tags, maxTags) => {
32
32
  validateTagCount(tags, maxTags);
33
33
  return dedupeTags(tags);
34
34
  };
35
- const stmtFindMemoryIdByHash = db.prepare('SELECT id FROM memories WHERE hash = ?');
36
- const buildTagInsert = (memoryId, tags) => {
37
- const params = tags.flatMap((tag) => [memoryId, tag]);
38
- return { params };
39
- };
40
- const tagInsertStatements = [];
41
- const getInsertTagsStatement = (tagCount) => {
42
- const cached = tagInsertStatements[tagCount];
43
- if (cached)
44
- return cached;
45
- const placeholders = Array.from({ length: tagCount }, () => '(?, ?)').join(', ');
46
- const stmt = db.prepare(`INSERT OR IGNORE INTO tags (memory_id, tag) VALUES ${placeholders}`);
47
- tagInsertStatements[tagCount] = stmt;
48
- return stmt;
49
- };
50
35
  const findMemoryIdByHash = (hash) => {
36
+ const stmtFindMemoryIdByHash = prepareCached('SELECT id FROM memories WHERE hash = ?');
51
37
  const row = executeGet(stmtFindMemoryIdByHash, hash);
52
38
  if (!row)
53
39
  return undefined;
@@ -56,15 +42,12 @@ const findMemoryIdByHash = (hash) => {
56
42
  const insertTags = (memoryId, tags) => {
57
43
  if (tags.length === 0)
58
44
  return;
59
- const { params } = buildTagInsert(memoryId, tags);
60
- const stmt = getInsertTagsStatement(tags.length);
61
- executeRun(stmt, ...params);
45
+ const stmtInsertTags = prepareCached('INSERT OR IGNORE INTO tags (memory_id, tag) SELECT ?, value FROM json_each(?)');
46
+ executeRun(stmtInsertTags, memoryId, JSON.stringify(tags));
62
47
  };
63
48
  const buildHash = (content) => {
64
- // eslint-disable-next-line sonarjs/hashing -- MD5 used for non-security deduplication only.
65
- return crypto.createHash('md5').update(content).digest('hex');
49
+ return crypto.createHash('sha256').update(content).digest('hex');
66
50
  };
67
- const stmtInsertMemory = db.prepare('INSERT OR IGNORE INTO memories (content, hash, importance, memory_type) VALUES (?, ?, ?, ?) RETURNING id');
68
51
  const requireMemoryId = (id) => {
69
52
  if (id === undefined) {
70
53
  throw new Error('Failed to resolve memory id');
@@ -72,6 +55,7 @@ const requireMemoryId = (id) => {
72
55
  return id;
73
56
  };
74
57
  const resolveMemoryId = (content, hash, importance, memoryType) => {
58
+ const stmtInsertMemory = prepareCached('INSERT OR IGNORE INTO memories (content, hash, importance, memory_type) VALUES (?, ?, ?, ?) RETURNING id');
75
59
  const inserted = executeGet(stmtInsertMemory, content, hash, importance, memoryType);
76
60
  if (inserted) {
77
61
  return { id: toSafeInteger(inserted.id, 'id'), isNew: true };
@@ -92,15 +76,15 @@ export const createMemories = (items) => {
92
76
  return withImmediateTransaction(() => createMemoriesInTransaction(items));
93
77
  };
94
78
  const withSavepoint = (name, fn) => {
95
- db.exec(`SAVEPOINT ${name}`);
79
+ executeRun(prepareCached(`SAVEPOINT ${name}`));
96
80
  try {
97
81
  const result = fn();
98
- db.exec(`RELEASE ${name}`);
82
+ executeRun(prepareCached(`RELEASE ${name}`));
99
83
  return result;
100
84
  }
101
85
  catch (err) {
102
- db.exec(`ROLLBACK TO ${name}`);
103
- db.exec(`RELEASE ${name}`);
86
+ executeRun(prepareCached(`ROLLBACK TO ${name}`));
87
+ executeRun(prepareCached(`RELEASE ${name}`));
104
88
  throw err;
105
89
  }
106
90
  };
@@ -112,7 +96,7 @@ const createMemoriesInTransaction = (items) => {
112
96
  const item = items[i];
113
97
  if (!item)
114
98
  continue;
115
- const result = processCreateMemoriesItem(i, item);
99
+ const result = createMemoryWithSavepoint(i, item);
116
100
  results.push(result);
117
101
  if (result.ok) {
118
102
  succeeded++;
@@ -123,7 +107,7 @@ const createMemoriesInTransaction = (items) => {
123
107
  }
124
108
  return { results, succeeded, failed };
125
109
  };
126
- const processCreateMemoriesItem = (index, item) => {
110
+ const createMemoryWithSavepoint = (index, item) => {
127
111
  const savepointName = `mem_item_${index}`;
128
112
  try {
129
113
  const created = withSavepoint(savepointName, () => createMemoryInTransaction(item));
@@ -139,9 +123,8 @@ const processCreateMemoriesItem = (index, item) => {
139
123
  return { ok: false, index, error: message };
140
124
  }
141
125
  };
142
- const stmtDeleteTagsForMemory = db.prepare('DELETE FROM tags WHERE memory_id = ?');
143
- const stmtUpdateContent = db.prepare('UPDATE memories SET content = ?, hash = ? WHERE id = ?');
144
126
  const replaceTags = (memoryId, tags) => {
127
+ const stmtDeleteTagsForMemory = prepareCached('DELETE FROM tags WHERE memory_id = ?');
145
128
  executeRun(stmtDeleteTagsForMemory, memoryId);
146
129
  insertTags(memoryId, normalizeTags(tags, MAX_TAGS));
147
130
  };
@@ -162,6 +145,7 @@ export const updateMemory = (hash, options) => {
162
145
  // Check if new content would create a duplicate
163
146
  assertNoDuplicateOnUpdate(hash, newHash);
164
147
  // Update content and hash
148
+ const stmtUpdateContent = prepareCached('UPDATE memories SET content = ?, hash = ? WHERE id = ?');
165
149
  executeRun(stmtUpdateContent, options.content, newHash, memoryId);
166
150
  // Update tags if provided, otherwise preserve existing tags
167
151
  if (options.tags !== undefined) {
@@ -170,3 +154,4 @@ export const updateMemory = (hash, options) => {
170
154
  return { updated: true, oldHash: hash, newHash };
171
155
  });
172
156
  };
157
+ //# sourceMappingURL=memory-write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-write.js","sourceRoot":"","sources":["../../src/core/memory-write.ts"],"names":[],"mappings":"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"}
@@ -13,3 +13,4 @@ export declare const deleteRelationship: (input: {
13
13
  to_hash: string;
14
14
  relation_type: string;
15
15
  }) => StatementResult;
16
+ //# sourceMappingURL=relationships.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relationships.d.ts","sourceRoot":"","sources":["../../src/core/relationships.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,YAAY,EACZ,eAAe,EAChB,MAAM,aAAa,CAAC;AA4BrB,eAAO,MAAM,kBAAkB,GAAI,OAAO;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;CACvB,KAAG,wBAyCA,CAAC;AA2BL,eAAO,MAAM,gBAAgB,GAAI,OAAO;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,MAAM,CAAC;CAC9C,KAAG,YAAY,EAQf,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,OAAO;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;CACvB,KAAG,eAcH,CAAC"}
@@ -1,6 +1,6 @@
1
- import { db, executeAll, executeGet, executeRun, mapRowToRelationship, toSafeInteger, withImmediateTransaction, } from './db.js';
2
- const stmtFindMemoryIdByHash = db.prepare('SELECT id FROM memories WHERE hash = ?');
1
+ import { executeAll, executeGet, executeRun, mapRowToRelationship, prepareCached, toSafeInteger, withImmediateTransaction, } from './db.js';
3
2
  const findMemoryIdByHash = (hash) => {
3
+ const stmtFindMemoryIdByHash = prepareCached('SELECT id FROM memories WHERE hash = ?');
4
4
  const row = executeGet(stmtFindMemoryIdByHash, hash);
5
5
  if (!row)
6
6
  return undefined;
@@ -13,26 +13,26 @@ const requireMemoryId = (hash) => {
13
13
  }
14
14
  return id;
15
15
  };
16
- const stmtInsertRelationship = db.prepare(`
17
- INSERT OR IGNORE INTO relationships (from_memory_id, to_memory_id, relation_type)
18
- VALUES (?, ?, ?)
19
- RETURNING id
20
- `);
21
- const stmtFindRelationshipId = db.prepare(`
22
- SELECT id FROM relationships
23
- WHERE from_memory_id = ? AND to_memory_id = ? AND relation_type = ?
24
- `);
25
16
  export const createRelationship = (input) => withImmediateTransaction(() => {
26
17
  const fromId = requireMemoryId(input.from_hash);
27
18
  const toId = requireMemoryId(input.to_hash);
28
19
  if (fromId === toId) {
29
20
  throw new Error('Cannot create self-referential relationship');
30
21
  }
22
+ const stmtInsertRelationship = prepareCached(`
23
+ INSERT OR IGNORE INTO relationships (from_memory_id, to_memory_id, relation_type)
24
+ VALUES (?, ?, ?)
25
+ RETURNING id
26
+ `);
31
27
  const inserted = executeGet(stmtInsertRelationship, fromId, toId, input.relation_type);
32
28
  if (inserted) {
33
29
  return { id: toSafeInteger(inserted.id, 'id'), isNew: true };
34
30
  }
35
31
  // Relationship already exists, find its ID
32
+ const stmtFindRelationshipId = prepareCached(`
33
+ SELECT id FROM relationships
34
+ WHERE from_memory_id = ? AND to_memory_id = ? AND relation_type = ?
35
+ `);
36
36
  const existing = executeGet(stmtFindRelationshipId, fromId, toId, input.relation_type);
37
37
  if (!existing) {
38
38
  throw new Error('Failed to resolve relationship id');
@@ -58,25 +58,21 @@ const buildGetRelationshipsQuery = (direction) => {
58
58
  return `${baseSelect} WHERE mf.hash = ? OR mt.hash = ?${orderBy}`;
59
59
  }
60
60
  };
61
- const stmtGetRelationships = {
62
- outgoing: db.prepare(buildGetRelationshipsQuery('outgoing')),
63
- incoming: db.prepare(buildGetRelationshipsQuery('incoming')),
64
- both: db.prepare(buildGetRelationshipsQuery('both')),
65
- };
66
61
  export const getRelationships = (input) => {
67
62
  const direction = input.direction ?? 'both';
68
- const stmt = stmtGetRelationships[direction];
63
+ const stmt = prepareCached(buildGetRelationshipsQuery(direction));
69
64
  const params = direction === 'both' ? [input.hash, input.hash] : [input.hash];
70
65
  const rows = executeAll(stmt, ...params);
71
66
  return rows.map(mapRowToRelationship);
72
67
  };
73
- const stmtDeleteRelationship = db.prepare(`
68
+ export const deleteRelationship = (input) => {
69
+ const stmtDeleteRelationship = prepareCached(`
74
70
  DELETE FROM relationships
75
71
  WHERE from_memory_id = (SELECT id FROM memories WHERE hash = ?)
76
72
  AND to_memory_id = (SELECT id FROM memories WHERE hash = ?)
77
73
  AND relation_type = ?
78
74
  `);
79
- export const deleteRelationship = (input) => {
80
75
  const result = executeRun(stmtDeleteRelationship, input.from_hash, input.to_hash, input.relation_type);
81
76
  return { changes: toSafeInteger(result.changes, 'changes') };
82
77
  };
78
+ //# sourceMappingURL=relationships.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relationships.js","sourceRoot":"","sources":["../../src/core/relationships.ts"],"names":[],"mappings":"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"}
@@ -2,9 +2,10 @@ import type { RecallResult, SearchResult } from '../types.js';
2
2
  interface SearchInput {
3
3
  query: string;
4
4
  }
5
- export declare const searchMemories: (input: SearchInput) => SearchResult[];
5
+ export declare const searchMemories: (input: SearchInput, signal?: AbortSignal) => SearchResult[];
6
6
  export declare const recallMemories: (input: {
7
7
  query: string;
8
8
  depth?: number;
9
- }) => RecallResult;
9
+ }, signal?: AbortSignal) => RecallResult;
10
10
  export {};
11
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/core/search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA0H9D,UAAU,WAAW;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAiBD,eAAO,MAAM,cAAc,GACzB,OAAO,WAAW,EAClB,SAAS,WAAW,KACnB,YAAY,EAcd,CAAC;AAiIF,eAAO,MAAM,cAAc,GACzB,OAAO;IACL,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,EACD,SAAS,WAAW,KACnB,YAiBF,CAAC"}