@memextend/core 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.
Files changed (81) hide show
  1. package/dist/embedding/index.d.ts +3 -0
  2. package/dist/embedding/index.d.ts.map +1 -0
  3. package/dist/embedding/index.js +4 -0
  4. package/dist/embedding/index.js.map +1 -0
  5. package/dist/embedding/local.d.ts +54 -0
  6. package/dist/embedding/local.d.ts.map +1 -0
  7. package/dist/embedding/local.js +162 -0
  8. package/dist/embedding/local.js.map +1 -0
  9. package/dist/embedding/local.test.d.ts +2 -0
  10. package/dist/embedding/local.test.d.ts.map +1 -0
  11. package/dist/embedding/local.test.js +73 -0
  12. package/dist/embedding/local.test.js.map +1 -0
  13. package/dist/index.d.ts +5 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +7 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/memory/capture.d.ts +102 -0
  18. package/dist/memory/capture.d.ts.map +1 -0
  19. package/dist/memory/capture.js +249 -0
  20. package/dist/memory/capture.js.map +1 -0
  21. package/dist/memory/capture.test.d.ts +2 -0
  22. package/dist/memory/capture.test.d.ts.map +1 -0
  23. package/dist/memory/capture.test.js +168 -0
  24. package/dist/memory/capture.test.js.map +1 -0
  25. package/dist/memory/deduplicate.d.ts +31 -0
  26. package/dist/memory/deduplicate.d.ts.map +1 -0
  27. package/dist/memory/deduplicate.js +64 -0
  28. package/dist/memory/deduplicate.js.map +1 -0
  29. package/dist/memory/deduplicate.test.d.ts +2 -0
  30. package/dist/memory/deduplicate.test.d.ts.map +1 -0
  31. package/dist/memory/deduplicate.test.js +116 -0
  32. package/dist/memory/deduplicate.test.js.map +1 -0
  33. package/dist/memory/index.d.ts +8 -0
  34. package/dist/memory/index.d.ts.map +1 -0
  35. package/dist/memory/index.js +7 -0
  36. package/dist/memory/index.js.map +1 -0
  37. package/dist/memory/retrieve.d.ts +62 -0
  38. package/dist/memory/retrieve.d.ts.map +1 -0
  39. package/dist/memory/retrieve.js +218 -0
  40. package/dist/memory/retrieve.js.map +1 -0
  41. package/dist/memory/retrieve.test.d.ts +2 -0
  42. package/dist/memory/retrieve.test.d.ts.map +1 -0
  43. package/dist/memory/retrieve.test.js +177 -0
  44. package/dist/memory/retrieve.test.js.map +1 -0
  45. package/dist/memory/types.d.ts +36 -0
  46. package/dist/memory/types.d.ts.map +1 -0
  47. package/dist/memory/types.js +4 -0
  48. package/dist/memory/types.js.map +1 -0
  49. package/dist/memory/types.test.d.ts +2 -0
  50. package/dist/memory/types.test.d.ts.map +1 -0
  51. package/dist/memory/types.test.js +31 -0
  52. package/dist/memory/types.test.js.map +1 -0
  53. package/dist/storage/index.d.ts +4 -0
  54. package/dist/storage/index.d.ts.map +1 -0
  55. package/dist/storage/index.js +5 -0
  56. package/dist/storage/index.js.map +1 -0
  57. package/dist/storage/lancedb.d.ts +24 -0
  58. package/dist/storage/lancedb.d.ts.map +1 -0
  59. package/dist/storage/lancedb.js +106 -0
  60. package/dist/storage/lancedb.js.map +1 -0
  61. package/dist/storage/lancedb.test.d.ts +2 -0
  62. package/dist/storage/lancedb.test.d.ts.map +1 -0
  63. package/dist/storage/lancedb.test.js +67 -0
  64. package/dist/storage/lancedb.test.js.map +1 -0
  65. package/dist/storage/sqlite.d.ts +68 -0
  66. package/dist/storage/sqlite.d.ts.map +1 -0
  67. package/dist/storage/sqlite.js +354 -0
  68. package/dist/storage/sqlite.js.map +1 -0
  69. package/dist/storage/sqlite.test.d.ts +2 -0
  70. package/dist/storage/sqlite.test.d.ts.map +1 -0
  71. package/dist/storage/sqlite.test.js +137 -0
  72. package/dist/storage/sqlite.test.js.map +1 -0
  73. package/dist/utils/index.d.ts +2 -0
  74. package/dist/utils/index.d.ts.map +1 -0
  75. package/dist/utils/index.js +4 -0
  76. package/dist/utils/index.js.map +1 -0
  77. package/dist/utils/project.d.ts +13 -0
  78. package/dist/utils/project.d.ts.map +1 -0
  79. package/dist/utils/project.js +37 -0
  80. package/dist/utils/project.js.map +1 -0
  81. package/package.json +61 -0
@@ -0,0 +1,36 @@
1
+ export interface Memory {
2
+ id: string;
3
+ projectId: string | null;
4
+ content: string;
5
+ type: MemoryType;
6
+ sourceTool: SourceTool | null;
7
+ createdAt: string;
8
+ sessionId: string | null;
9
+ metadata: Record<string, unknown> | null;
10
+ }
11
+ export type MemoryType = 'tool_capture' | 'reasoning' | 'summary' | 'manual';
12
+ export type SourceTool = 'Edit' | 'Write' | 'Bash' | 'Task';
13
+ export interface Project {
14
+ id: string;
15
+ name: string;
16
+ path: string;
17
+ createdAt: string;
18
+ }
19
+ export interface GlobalProfile {
20
+ id: string;
21
+ key: 'preference' | 'pattern' | 'fact';
22
+ content: string;
23
+ createdAt: string;
24
+ }
25
+ export interface SearchResult {
26
+ memory: Memory;
27
+ score: number;
28
+ source: 'fts' | 'vector' | 'hybrid';
29
+ }
30
+ export interface RetrievalOptions {
31
+ projectId?: string;
32
+ limit?: number;
33
+ recentDays?: number;
34
+ includeGlobal?: boolean;
35
+ }
36
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/memory/types.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,UAAU,CAAC;IACjB,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC1C;AAED,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE7E,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAE5D,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,YAAY,GAAG,SAAS,GAAG,MAAM,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAC;CACrC;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB"}
@@ -0,0 +1,4 @@
1
+ // packages/core/src/memory/types.ts
2
+ // Copyright (c) 2026 ZodTTD LLC. MIT License.
3
+ export {};
4
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/memory/types.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,8CAA8C"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.test.d.ts","sourceRoot":"","sources":["../../src/memory/types.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,31 @@
1
+ // packages/core/src/memory/types.test.ts
2
+ import { describe, it, expect } from 'vitest';
3
+ describe('Memory types', () => {
4
+ it('should allow valid Memory object', () => {
5
+ const memory = {
6
+ id: '123',
7
+ projectId: 'proj-1',
8
+ content: 'Test memory',
9
+ type: 'tool_capture',
10
+ sourceTool: 'Edit',
11
+ createdAt: new Date().toISOString(),
12
+ sessionId: 'sess-1',
13
+ metadata: { file: 'test.ts' }
14
+ };
15
+ expect(memory.id).toBe('123');
16
+ });
17
+ it('should allow null projectId for global memories', () => {
18
+ const memory = {
19
+ id: '456',
20
+ projectId: null,
21
+ content: 'Global preference',
22
+ type: 'manual',
23
+ sourceTool: null,
24
+ createdAt: new Date().toISOString(),
25
+ sessionId: null,
26
+ metadata: null
27
+ };
28
+ expect(memory.projectId).toBeNull();
29
+ });
30
+ });
31
+ //# sourceMappingURL=types.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.test.js","sourceRoot":"","sources":["../../src/memory/types.test.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAG9C,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,MAAM,GAAW;YACrB,EAAE,EAAE,KAAK;YACT,SAAS,EAAE,QAAQ;YACnB,OAAO,EAAE,aAAa;YACtB,IAAI,EAAE,cAAc;YACpB,UAAU,EAAE,MAAM;YAClB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,SAAS,EAAE,QAAQ;YACnB,QAAQ,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;SAC9B,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,MAAM,GAAW;YACrB,EAAE,EAAE,KAAK;YACT,SAAS,EAAE,IAAI;YACf,OAAO,EAAE,mBAAmB;YAC5B,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,IAAI;YAChB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,SAAS,EAAE,IAAI;YACf,QAAQ,EAAE,IAAI;SACf,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { SQLiteStorage } from './sqlite.js';
2
+ export { LanceDBStorage } from './lancedb.js';
3
+ export type { VectorSearchResult } from './lancedb.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,5 @@
1
+ // packages/core/src/storage/index.ts
2
+ // Copyright (c) 2026 ZodTTD LLC. MIT License.
3
+ export { SQLiteStorage } from './sqlite.js';
4
+ export { LanceDBStorage } from './lancedb.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,8CAA8C;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,24 @@
1
+ export interface VectorSearchResult {
2
+ id: string;
3
+ score: number;
4
+ }
5
+ export declare class LanceDBStorage {
6
+ private db;
7
+ private table;
8
+ private readonly tableName;
9
+ private readonly dimensions;
10
+ private constructor();
11
+ static create(dbPath: string): Promise<LanceDBStorage>;
12
+ private initialize;
13
+ insertVector(id: string, vector: number[]): Promise<void>;
14
+ insertVectors(items: Array<{
15
+ id: string;
16
+ vector: number[];
17
+ }>): Promise<void>;
18
+ search(vector: number[], limit?: number): Promise<VectorSearchResult[]>;
19
+ deleteVector(id: string): Promise<void>;
20
+ getVectorCount(): Promise<number>;
21
+ getVectorsByIds(ids: string[]): Promise<Map<string, number[]>>;
22
+ close(): Promise<void>;
23
+ }
24
+ //# sourceMappingURL=lancedb.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lancedb.d.ts","sourceRoot":"","sources":["../../src/storage/lancedb.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,EAAE,CAAqB;IAC/B,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;IACxC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAO;IAElC,OAAO;WAIM,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;YAO9C,UAAU;IAQlB,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAczD,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAc5E,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAmB3E,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOvC,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAKjC,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IA8B9D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
@@ -0,0 +1,106 @@
1
+ // packages/core/src/storage/lancedb.ts
2
+ // Copyright (c) 2026 ZodTTD LLC. MIT License.
3
+ import * as lancedb from '@lancedb/lancedb';
4
+ export class LanceDBStorage {
5
+ db;
6
+ table = null;
7
+ tableName = 'memories';
8
+ dimensions = 384;
9
+ constructor(db) {
10
+ this.db = db;
11
+ }
12
+ static async create(dbPath) {
13
+ const db = await lancedb.connect(dbPath);
14
+ const storage = new LanceDBStorage(db);
15
+ await storage.initialize();
16
+ return storage;
17
+ }
18
+ async initialize() {
19
+ const tableNames = await this.db.tableNames();
20
+ if (tableNames.includes(this.tableName)) {
21
+ this.table = await this.db.openTable(this.tableName);
22
+ }
23
+ }
24
+ async insertVector(id, vector) {
25
+ if (vector.length !== this.dimensions) {
26
+ throw new Error(`Vector must have ${this.dimensions} dimensions, got ${vector.length}`);
27
+ }
28
+ const data = [{ id, vector }];
29
+ if (!this.table) {
30
+ this.table = await this.db.createTable(this.tableName, data);
31
+ }
32
+ else {
33
+ await this.table.add(data);
34
+ }
35
+ }
36
+ async insertVectors(items) {
37
+ for (const item of items) {
38
+ if (item.vector.length !== this.dimensions) {
39
+ throw new Error(`Vector must have ${this.dimensions} dimensions, got ${item.vector.length}`);
40
+ }
41
+ }
42
+ if (!this.table) {
43
+ this.table = await this.db.createTable(this.tableName, items);
44
+ }
45
+ else {
46
+ await this.table.add(items);
47
+ }
48
+ }
49
+ async search(vector, limit = 10) {
50
+ if (!this.table) {
51
+ return [];
52
+ }
53
+ // LanceDB requires k > 0, so default 0 to a reasonable max
54
+ const effectiveLimit = limit > 0 ? limit : 100;
55
+ const results = await this.table
56
+ .vectorSearch(vector)
57
+ .limit(effectiveLimit)
58
+ .toArray();
59
+ return results.map(row => ({
60
+ id: row.id,
61
+ score: 1 - row._distance // Convert distance to similarity
62
+ }));
63
+ }
64
+ async deleteVector(id) {
65
+ if (!this.table)
66
+ return;
67
+ // Sanitize the ID to prevent injection (escape single quotes)
68
+ const sanitizedId = id.replace(/'/g, "''");
69
+ await this.table.delete(`id = '${sanitizedId}'`);
70
+ }
71
+ async getVectorCount() {
72
+ if (!this.table)
73
+ return 0;
74
+ return await this.table.countRows();
75
+ }
76
+ async getVectorsByIds(ids) {
77
+ const result = new Map();
78
+ if (!this.table || ids.length === 0)
79
+ return result;
80
+ // Batch queries to avoid extremely long WHERE clauses
81
+ const BATCH_SIZE = 100;
82
+ try {
83
+ for (let i = 0; i < ids.length; i += BATCH_SIZE) {
84
+ const batch = ids.slice(i, i + BATCH_SIZE);
85
+ // Sanitize IDs to prevent injection
86
+ const sanitizedIds = batch.map(id => id.replace(/'/g, "''"));
87
+ const filter = sanitizedIds.map(id => `id = '${id}'`).join(' OR ');
88
+ const rows = await this.table
89
+ .query()
90
+ .where(filter)
91
+ .toArray();
92
+ for (const row of rows) {
93
+ result.set(row.id, row.vector);
94
+ }
95
+ }
96
+ }
97
+ catch {
98
+ // Return empty map on error
99
+ }
100
+ return result;
101
+ }
102
+ async close() {
103
+ // LanceDB doesn't require explicit close
104
+ }
105
+ }
106
+ //# sourceMappingURL=lancedb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lancedb.js","sourceRoot":"","sources":["../../src/storage/lancedb.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=lancedb.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lancedb.test.d.ts","sourceRoot":"","sources":["../../src/storage/lancedb.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,67 @@
1
+ // packages/core/src/storage/lancedb.test.ts
2
+ // Copyright (c) 2026 ZodTTD LLC. MIT License.
3
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
4
+ import { mkdtemp, rm } from 'fs/promises';
5
+ import { join } from 'path';
6
+ import { tmpdir } from 'os';
7
+ import { LanceDBStorage } from './lancedb.js';
8
+ describe('LanceDBStorage', () => {
9
+ let tempDir;
10
+ let storage;
11
+ beforeEach(async () => {
12
+ tempDir = await mkdtemp(join(tmpdir(), 'memextend-lance-test-'));
13
+ storage = await LanceDBStorage.create(tempDir);
14
+ });
15
+ afterEach(async () => {
16
+ await storage.close();
17
+ await rm(tempDir, { recursive: true });
18
+ });
19
+ it('should insert and search vectors', async () => {
20
+ const vector = new Array(384).fill(0).map(() => Math.random());
21
+ await storage.insertVector('mem-1', vector);
22
+ const results = await storage.search(vector, 5);
23
+ expect(results.length).toBeGreaterThan(0);
24
+ expect(results[0].id).toBe('mem-1');
25
+ });
26
+ it('should return similar vectors first', async () => {
27
+ const baseVector = new Array(384).fill(0.5);
28
+ const similarVector = new Array(384).fill(0.5).map(v => v + (Math.random() - 0.5) * 0.1);
29
+ const differentVector = new Array(384).fill(0).map(() => Math.random());
30
+ await storage.insertVector('similar', similarVector);
31
+ await storage.insertVector('different', differentVector);
32
+ const results = await storage.search(baseVector, 2);
33
+ expect(results[0].id).toBe('similar');
34
+ });
35
+ it('should validate vector dimensions', async () => {
36
+ const wrongDimensions = new Array(100).fill(0.5);
37
+ await expect(storage.insertVector('wrong', wrongDimensions))
38
+ .rejects.toThrow('Vector must have 384 dimensions');
39
+ });
40
+ it('should batch insert vectors', async () => {
41
+ const items = [
42
+ { id: 'batch-1', vector: new Array(384).fill(0.1) },
43
+ { id: 'batch-2', vector: new Array(384).fill(0.2) },
44
+ { id: 'batch-3', vector: new Array(384).fill(0.3) },
45
+ ];
46
+ await storage.insertVectors(items);
47
+ const count = await storage.getVectorCount();
48
+ expect(count).toBe(3);
49
+ });
50
+ it('should delete vectors', async () => {
51
+ const vector = new Array(384).fill(0.5);
52
+ await storage.insertVector('to-delete', vector);
53
+ await storage.deleteVector('to-delete');
54
+ const results = await storage.search(vector, 5);
55
+ const found = results.find(r => r.id === 'to-delete');
56
+ expect(found).toBeUndefined();
57
+ });
58
+ it('should return empty results when no table exists', async () => {
59
+ const freshDir = await mkdtemp(join(tmpdir(), 'memextend-lance-empty-'));
60
+ const freshStorage = await LanceDBStorage.create(freshDir);
61
+ const results = await freshStorage.search(new Array(384).fill(0.5), 5);
62
+ expect(results).toEqual([]);
63
+ await freshStorage.close();
64
+ await rm(freshDir, { recursive: true });
65
+ });
66
+ });
67
+ //# sourceMappingURL=lancedb.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lancedb.test.js","sourceRoot":"","sources":["../../src/storage/lancedb.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ import type { Memory, Project, GlobalProfile, SearchResult } from '../memory/types.js';
2
+ export declare class SQLiteStorage {
3
+ private db;
4
+ constructor(dbPath: string);
5
+ private initialize;
6
+ getTables(): string[];
7
+ insertMemory(memory: Memory): void;
8
+ getMemory(id: string): Memory | null;
9
+ getAllMemories(projectId?: string, limit?: number): Memory[];
10
+ searchFTS(query: string, limit?: number): SearchResult[];
11
+ getRecentMemories(projectId: string | null, limit?: number, days?: number): Memory[];
12
+ deleteMemory(id: string): boolean;
13
+ updateMemory(id: string, content: string): boolean;
14
+ deleteAllMemories(projectId?: string): number;
15
+ deleteMemoriesBefore(date: Date, projectId?: string): number;
16
+ insertProject(project: Project): void;
17
+ getProject(id: string): Project | null;
18
+ /**
19
+ * Find a project by name (case-insensitive).
20
+ * Returns the first matching project, preferring projects with a path set.
21
+ */
22
+ getProjectByName(name: string): Project | null;
23
+ /**
24
+ * Delete a project and all its memories.
25
+ * @returns Object with counts of deleted project and memories
26
+ */
27
+ deleteProject(projectId: string): {
28
+ projectDeleted: boolean;
29
+ memoriesDeleted: number;
30
+ };
31
+ /**
32
+ * Get all projects.
33
+ */
34
+ getAllProjects(): Project[];
35
+ insertGlobalProfile(profile: GlobalProfile): void;
36
+ getGlobalProfiles(limit?: number): GlobalProfile[];
37
+ /**
38
+ * Delete a specific global profile by ID.
39
+ */
40
+ deleteGlobalProfile(id: string): boolean;
41
+ /**
42
+ * Delete all global profiles.
43
+ * @returns Number of profiles deleted
44
+ */
45
+ deleteAllGlobalProfiles(): number;
46
+ getMemoryCount(): number;
47
+ getMemoryCountByProject(projectId: string): number;
48
+ /**
49
+ * Get IDs of oldest memories for a project, exceeding the limit
50
+ * @returns Array of memory IDs to delete (oldest first)
51
+ */
52
+ getOldestMemoryIds(projectId: string | null, limit: number): string[];
53
+ /**
54
+ * Prune memories to stay within limits
55
+ * @returns Number of memories deleted
56
+ */
57
+ pruneMemories(options: {
58
+ maxPerProject?: number;
59
+ maxTotal?: number;
60
+ projectId?: string;
61
+ }): {
62
+ deleted: number;
63
+ deletedIds: string[];
64
+ };
65
+ private rowToMemory;
66
+ close(): void;
67
+ }
68
+ //# sourceMappingURL=sqlite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/storage/sqlite.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvF,qBAAa,aAAa;IACxB,OAAO,CAAC,EAAE,CAAoB;gBAElB,MAAM,EAAE,MAAM;IAM1B,OAAO,CAAC,UAAU;IAgDlB,SAAS,IAAI,MAAM,EAAE;IAQrB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAiBlC,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAMpC,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,KAAK,GAAE,MAAY,GAAG,MAAM,EAAE;IAgBjE,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,YAAY,EAAE;IAiB5D,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,GAAE,MAAU,EAAE,IAAI,GAAE,MAAU,GAAG,MAAM,EAAE;IAoC1F,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAKjC,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO;IASlD,iBAAiB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM;IAU7C,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM;IAc5D,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAQrC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI;IAWtC;;;OAGG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI;IA6B9C;;;OAGG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG;QAAE,cAAc,EAAE,OAAO,CAAC;QAAC,eAAe,EAAE,MAAM,CAAA;KAAE;IAatF;;OAEG;IACH,cAAc,IAAI,OAAO,EAAE;IAW3B,mBAAmB,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAQjD,iBAAiB,CAAC,KAAK,GAAE,MAAW,GAAG,aAAa,EAAE;IAYtD;;OAEG;IACH,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAKxC;;;OAGG;IACH,uBAAuB,IAAI,MAAM;IAKjC,cAAc,IAAI,MAAM;IAKxB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAOlD;;;OAGG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IAyBrE;;;OAGG;IACH,aAAa,CAAC,OAAO,EAAE;QACrB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,EAAE,CAAA;KAAE;IAkC7C,OAAO,CAAC,WAAW;IAanB,KAAK,IAAI,IAAI;CAGd"}