@j0hanz/memdb 1.0.8 → 1.0.10
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/core/database-schema.d.ts +3 -0
- package/dist/core/database-schema.d.ts.map +1 -0
- package/dist/core/database-schema.js +65 -0
- package/dist/core/database-schema.js.map +1 -0
- package/dist/core/database.d.ts +4 -0
- package/dist/core/database.d.ts.map +1 -0
- package/dist/core/database.js +44 -0
- package/dist/core/database.js.map +1 -0
- package/dist/core/memory-create.d.ts +8 -0
- package/dist/core/memory-create.d.ts.map +1 -0
- package/dist/core/memory-create.js +34 -0
- package/dist/core/memory-create.js.map +1 -0
- package/dist/core/memory-db.d.ts +3 -0
- package/dist/core/memory-db.d.ts.map +1 -0
- package/dist/core/memory-db.js +32 -0
- package/dist/core/memory-db.js.map +1 -0
- package/dist/core/memory-read.d.ts +4 -0
- package/dist/core/memory-read.d.ts.map +1 -0
- package/dist/core/memory-read.js +14 -0
- package/dist/core/memory-read.js.map +1 -0
- package/dist/core/memory-relations.d.ts +11 -0
- package/dist/core/memory-relations.d.ts.map +1 -0
- package/dist/core/memory-relations.js +58 -0
- package/dist/core/memory-relations.js.map +1 -0
- package/dist/core/memory-search.d.ts +9 -0
- package/dist/core/memory-search.d.ts.map +1 -0
- package/dist/core/memory-search.js +17 -0
- package/dist/core/memory-search.js.map +1 -0
- package/dist/core/memory-stats.d.ts +3 -0
- package/dist/core/memory-stats.d.ts.map +1 -0
- package/dist/core/memory-stats.js +52 -0
- package/dist/core/memory-stats.js.map +1 -0
- package/dist/core/memory-updates.d.ts +11 -0
- package/dist/core/memory-updates.d.ts.map +1 -0
- package/dist/core/memory-updates.js +116 -0
- package/dist/core/memory-updates.js.map +1 -0
- package/dist/core/relation-queries.d.ts +8 -0
- package/dist/core/relation-queries.d.ts.map +1 -0
- package/dist/core/relation-queries.js +126 -0
- package/dist/core/relation-queries.js.map +1 -0
- package/dist/core/row-mappers.d.ts +7 -0
- package/dist/core/row-mappers.d.ts.map +1 -0
- package/dist/core/row-mappers.js +53 -0
- package/dist/core/row-mappers.js.map +1 -0
- package/dist/core/search-errors.d.ts +2 -0
- package/dist/core/search-errors.d.ts.map +1 -0
- package/dist/core/search-errors.js +31 -0
- package/dist/core/search-errors.js.map +1 -0
- package/dist/core/search.d.ts +13 -0
- package/dist/core/search.d.ts.map +1 -0
- package/dist/core/search.js +88 -0
- package/dist/core/search.js.map +1 -0
- package/dist/core/sqlite.d.ts +11 -0
- package/dist/core/sqlite.d.ts.map +1 -0
- package/dist/core/sqlite.js +74 -0
- package/dist/core/sqlite.js.map +1 -0
- package/dist/core/tags.d.ts +2 -0
- package/dist/core/tags.d.ts.map +1 -0
- package/dist/core/tags.js +28 -0
- package/dist/core/tags.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +77 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/errors.d.ts +20 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +23 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/schemas/inputs.d.ts +45 -0
- package/dist/schemas/inputs.d.ts.map +1 -0
- package/dist/schemas/inputs.js +98 -0
- package/dist/schemas/inputs.js.map +1 -0
- package/dist/schemas/outputs.d.ts +10 -0
- package/dist/schemas/outputs.d.ts.map +1 -0
- package/dist/schemas/outputs.js +29 -0
- package/dist/schemas/outputs.js.map +1 -0
- package/dist/tools/definitions/memory-core.d.ts +3 -0
- package/dist/tools/definitions/memory-core.d.ts.map +1 -0
- package/dist/tools/definitions/memory-core.js +80 -0
- package/dist/tools/definitions/memory-core.js.map +1 -0
- package/dist/tools/definitions/memory-relations.d.ts +3 -0
- package/dist/tools/definitions/memory-relations.d.ts.map +1 -0
- package/dist/tools/definitions/memory-relations.js +44 -0
- package/dist/tools/definitions/memory-relations.js.map +1 -0
- package/dist/tools/definitions/memory-search.d.ts +3 -0
- package/dist/tools/definitions/memory-search.d.ts.map +1 -0
- package/dist/tools/definitions/memory-search.js +30 -0
- package/dist/tools/definitions/memory-search.js.map +1 -0
- package/dist/tools/definitions/memory-stats.d.ts +3 -0
- package/dist/tools/definitions/memory-stats.d.ts.map +1 -0
- package/dist/tools/definitions/memory-stats.js +21 -0
- package/dist/tools/definitions/memory-stats.js.map +1 -0
- package/dist/tools/index.d.ts +3 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +16 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/tool-handlers.d.ts +4 -0
- package/dist/tools/tool-handlers.d.ts.map +1 -0
- package/dist/tools/tool-handlers.js +20 -0
- package/dist/tools/tool-handlers.js.map +1 -0
- package/dist/tools/tool-types.d.ts +15 -0
- package/dist/tools/tool-types.d.ts.map +1 -0
- package/dist/tools/tool-types.js +2 -0
- package/dist/tools/tool-types.js.map +1 -0
- package/dist/types/index.d.ts +38 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/config.d.ts +7 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +100 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/logger.d.ts +6 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +21 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { mapRowToRelatedMemory } from './row-mappers.js';
|
|
2
|
+
import { executeAll, prepareCached } from './sqlite.js';
|
|
3
|
+
const directConfig = {
|
|
4
|
+
outgoing: { joinColumn: 'to_memory_id', whereColumn: 'from_memory_id' },
|
|
5
|
+
incoming: { joinColumn: 'from_memory_id', whereColumn: 'to_memory_id' },
|
|
6
|
+
};
|
|
7
|
+
const recursiveConfig = {
|
|
8
|
+
outgoing: {
|
|
9
|
+
baseColumn: 'from_memory_id',
|
|
10
|
+
joinColumn: 'from_memory_id',
|
|
11
|
+
relsJoinColumn: 'to_id',
|
|
12
|
+
memoryJoinColumn: 'to_id',
|
|
13
|
+
},
|
|
14
|
+
incoming: {
|
|
15
|
+
baseColumn: 'to_memory_id',
|
|
16
|
+
joinColumn: 'to_memory_id',
|
|
17
|
+
relsJoinColumn: 'from_id',
|
|
18
|
+
memoryJoinColumn: 'from_id',
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
const typeFilter = (relationType) => relationType
|
|
22
|
+
? { clause: ' AND r.relation_type = ?', params: [relationType] }
|
|
23
|
+
: { clause: '', params: [] };
|
|
24
|
+
const run = (sql, params) => executeAll(prepareCached(sql), ...params).map((row) => mapRowToRelatedMemory(row));
|
|
25
|
+
const buildDirectSql = (input) => {
|
|
26
|
+
const config = directConfig[input.direction];
|
|
27
|
+
const limitClause = input.includeLimit === false ? '' : '\n LIMIT 1000';
|
|
28
|
+
return `
|
|
29
|
+
SELECT m.*, r.relation_type as relation_type, 1 as depth
|
|
30
|
+
FROM memories m
|
|
31
|
+
JOIN relationships r ON m.id = r.${config.joinColumn}
|
|
32
|
+
WHERE r.${config.whereColumn} = ?${input.clause}${limitClause}
|
|
33
|
+
`;
|
|
34
|
+
};
|
|
35
|
+
const buildRecursiveSql = (input) => {
|
|
36
|
+
const config = recursiveConfig[input.direction];
|
|
37
|
+
return `
|
|
38
|
+
WITH RECURSIVE rels(depth, from_id, to_id, relation_type) AS (
|
|
39
|
+
SELECT 1, r.from_memory_id, r.to_memory_id, r.relation_type
|
|
40
|
+
FROM relationships r
|
|
41
|
+
WHERE r.${config.baseColumn} = ?${input.clause}
|
|
42
|
+
UNION ALL
|
|
43
|
+
SELECT rels.depth + 1, r.from_memory_id, r.to_memory_id, r.relation_type
|
|
44
|
+
FROM relationships r
|
|
45
|
+
JOIN rels ON r.${config.joinColumn} = rels.${config.relsJoinColumn}
|
|
46
|
+
WHERE rels.depth < ?${input.clause}
|
|
47
|
+
)
|
|
48
|
+
SELECT m.*, rels.relation_type as relation_type, MIN(rels.depth) as depth
|
|
49
|
+
FROM rels
|
|
50
|
+
JOIN memories m ON m.id = rels.${config.memoryJoinColumn}
|
|
51
|
+
GROUP BY m.id, rels.relation_type
|
|
52
|
+
ORDER BY depth, m.id
|
|
53
|
+
LIMIT 1000
|
|
54
|
+
`;
|
|
55
|
+
};
|
|
56
|
+
const buildRecursiveParams = (input) => {
|
|
57
|
+
if (!input.relationType) {
|
|
58
|
+
return [input.memoryId, input.maxDepth];
|
|
59
|
+
}
|
|
60
|
+
return [input.memoryId, ...input.params, input.maxDepth, ...input.params];
|
|
61
|
+
};
|
|
62
|
+
export const queryOutgoingDirect = (memoryId, relationType) => {
|
|
63
|
+
const { clause, params } = typeFilter(relationType);
|
|
64
|
+
const sql = buildDirectSql({ direction: 'outgoing', clause });
|
|
65
|
+
return run(sql, [memoryId, ...params]);
|
|
66
|
+
};
|
|
67
|
+
export const queryIncomingDirect = (memoryId, relationType) => {
|
|
68
|
+
const { clause, params } = typeFilter(relationType);
|
|
69
|
+
const sql = buildDirectSql({ direction: 'incoming', clause });
|
|
70
|
+
return run(sql, [memoryId, ...params]);
|
|
71
|
+
};
|
|
72
|
+
export const queryBothDirect = (memoryId, relationType) => {
|
|
73
|
+
const { clause, params } = typeFilter(relationType);
|
|
74
|
+
const outgoingSql = buildDirectSql({
|
|
75
|
+
direction: 'outgoing',
|
|
76
|
+
clause,
|
|
77
|
+
includeLimit: false,
|
|
78
|
+
});
|
|
79
|
+
const incomingSql = buildDirectSql({
|
|
80
|
+
direction: 'incoming',
|
|
81
|
+
clause,
|
|
82
|
+
includeLimit: false,
|
|
83
|
+
});
|
|
84
|
+
const sql = `
|
|
85
|
+
${outgoingSql}
|
|
86
|
+
UNION
|
|
87
|
+
${incomingSql}
|
|
88
|
+
LIMIT 1000
|
|
89
|
+
`;
|
|
90
|
+
return run(sql, [memoryId, ...params, memoryId, ...params]);
|
|
91
|
+
};
|
|
92
|
+
export const queryOutgoingRecursive = (memoryId, relationType, maxDepth) => {
|
|
93
|
+
const { clause, params } = typeFilter(relationType);
|
|
94
|
+
const sql = buildRecursiveSql({ direction: 'outgoing', clause });
|
|
95
|
+
const sqlParams = buildRecursiveParams({
|
|
96
|
+
memoryId,
|
|
97
|
+
relationType,
|
|
98
|
+
maxDepth,
|
|
99
|
+
params,
|
|
100
|
+
});
|
|
101
|
+
return run(sql, sqlParams);
|
|
102
|
+
};
|
|
103
|
+
export const queryIncomingRecursive = (memoryId, relationType, maxDepth) => {
|
|
104
|
+
const { clause, params } = typeFilter(relationType);
|
|
105
|
+
const sql = buildRecursiveSql({ direction: 'incoming', clause });
|
|
106
|
+
const sqlParams = buildRecursiveParams({
|
|
107
|
+
memoryId,
|
|
108
|
+
relationType,
|
|
109
|
+
maxDepth,
|
|
110
|
+
params,
|
|
111
|
+
});
|
|
112
|
+
return run(sql, sqlParams);
|
|
113
|
+
};
|
|
114
|
+
export const deduplicateByHash = (memories) => {
|
|
115
|
+
const seen = new Map();
|
|
116
|
+
for (const mem of memories) {
|
|
117
|
+
const existing = seen.get(mem.hash);
|
|
118
|
+
if (!existing || mem.depth < existing.depth) {
|
|
119
|
+
seen.set(mem.hash, mem);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return [...seen.values()]
|
|
123
|
+
.sort((a, b) => a.depth - b.depth || a.id - b.id)
|
|
124
|
+
.slice(0, 1000);
|
|
125
|
+
};
|
|
126
|
+
//# sourceMappingURL=relation-queries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relation-queries.js","sourceRoot":"","sources":["../../src/core/relation-queries.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,aAAa,EAAiB,MAAM,aAAa,CAAC;AAIvE,MAAM,YAAY,GAGd;IACF,QAAQ,EAAE,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,gBAAgB,EAAE;IACvE,QAAQ,EAAE,EAAE,UAAU,EAAE,gBAAgB,EAAE,WAAW,EAAE,cAAc,EAAE;CACxE,CAAC;AAEF,MAAM,eAAe,GAQjB;IACF,QAAQ,EAAE;QACR,UAAU,EAAE,gBAAgB;QAC5B,UAAU,EAAE,gBAAgB;QAC5B,cAAc,EAAE,OAAO;QACvB,gBAAgB,EAAE,OAAO;KAC1B;IACD,QAAQ,EAAE;QACR,UAAU,EAAE,cAAc;QAC1B,UAAU,EAAE,cAAc;QAC1B,cAAc,EAAE,SAAS;QACzB,gBAAgB,EAAE,SAAS;KAC5B;CACF,CAAC;AAEF,MAAM,UAAU,GAAG,CACjB,YAAqB,EACiB,EAAE,CACxC,YAAY;IACV,CAAC,CAAC,EAAE,MAAM,EAAE,0BAA0B,EAAE,MAAM,EAAE,CAAC,YAAY,CAAC,EAAE;IAChE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;AAEjC,MAAM,GAAG,GAAG,CAAC,GAAW,EAAE,MAAkB,EAAmB,EAAE,CAC/D,UAAU,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,GAAU,EAAE,EAAE,CAC3D,qBAAqB,CAAC,GAAG,CAAC,CAC3B,CAAC;AAEJ,MAAM,cAAc,GAAG,CAAC,KAIvB,EAAU,EAAE;IACX,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC7C,MAAM,WAAW,GAAG,KAAK,CAAC,YAAY,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC;IAC3E,OAAO;;;uCAG8B,MAAM,CAAC,UAAU;cAC1C,MAAM,CAAC,WAAW,OAAO,KAAK,CAAC,MAAM,GAAG,WAAW;GAC9D,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,KAG1B,EAAU,EAAE;IACX,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAChD,OAAO;;;;gBAIO,MAAM,CAAC,UAAU,OAAO,KAAK,CAAC,MAAM;;;;uBAI7B,MAAM,CAAC,UAAU,WAAW,MAAM,CAAC,cAAc;4BAC5C,KAAK,CAAC,MAAM;;;;qCAIH,MAAM,CAAC,gBAAgB;;;;GAIzD,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAAG,CAAC,KAK7B,EAAuB,EAAE;IACxB,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;QACxB,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;AAC5E,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,QAAgB,EAChB,YAAqB,EACJ,EAAE;IACnB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;IACpD,MAAM,GAAG,GAAG,cAAc,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9D,OAAO,GAAG,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC;AACzC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,QAAgB,EAChB,YAAqB,EACJ,EAAE;IACnB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;IACpD,MAAM,GAAG,GAAG,cAAc,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9D,OAAO,GAAG,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC;AACzC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,QAAgB,EAChB,YAAqB,EACJ,EAAE;IACnB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;IACpD,MAAM,WAAW,GAAG,cAAc,CAAC;QACjC,SAAS,EAAE,UAAU;QACrB,MAAM;QACN,YAAY,EAAE,KAAK;KACpB,CAAC,CAAC;IACH,MAAM,WAAW,GAAG,cAAc,CAAC;QACjC,SAAS,EAAE,UAAU;QACrB,MAAM;QACN,YAAY,EAAE,KAAK;KACpB,CAAC,CAAC;IACH,MAAM,GAAG,GAAG;MACR,WAAW;;MAEX,WAAW;;GAEd,CAAC;IACF,OAAO,GAAG,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,GAAG,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC;AAC9D,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACpC,QAAgB,EAChB,YAAgC,EAChC,QAAgB,EACC,EAAE;IACnB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;IACpD,MAAM,GAAG,GAAG,iBAAiB,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC;IACjE,MAAM,SAAS,GAAG,oBAAoB,CAAC;QACrC,QAAQ;QACR,YAAY;QACZ,QAAQ;QACR,MAAM;KACP,CAAC,CAAC;IACH,OAAO,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;AAC7B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACpC,QAAgB,EAChB,YAAgC,EAChC,QAAgB,EACC,EAAE;IACnB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;IACpD,MAAM,GAAG,GAAG,iBAAiB,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC;IACjE,MAAM,SAAS,GAAG,oBAAoB,CAAC;QACrC,QAAQ;QACR,YAAY;QACZ,QAAQ;QACR,MAAM;KACP,CAAC,CAAC;IACH,OAAO,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;AAC7B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,QAAyB,EACR,EAAE;IACnB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC9C,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC;YAC5C,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;SACtB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;SAChD,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AACpB,CAAC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Memory, RelatedMemory, SearchResult } from '../types/index.js';
|
|
2
|
+
export type DbRow = Record<string, unknown>;
|
|
3
|
+
export declare const toSafeInteger: (value: unknown, field: string) => number;
|
|
4
|
+
export declare const mapRowToMemory: (row: DbRow) => Memory;
|
|
5
|
+
export declare const mapRowToSearchResult: (row: DbRow) => SearchResult;
|
|
6
|
+
export declare const mapRowToRelatedMemory: (row: DbRow) => RelatedMemory;
|
|
7
|
+
//# sourceMappingURL=row-mappers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"row-mappers.d.ts","sourceRoot":"","sources":["../../src/core/row-mappers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE7E,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAc5C,eAAO,MAAM,aAAa,GAAI,OAAO,OAAO,EAAE,OAAO,MAAM,KAAG,MAM7D,CAAC;AAuBF,eAAO,MAAM,cAAc,GAAI,KAAK,KAAK,KAAG,MAS1C,CAAC;AAEH,eAAO,MAAM,oBAAoB,GAAI,KAAK,KAAK,KAAG,YAGhD,CAAC;AAEH,eAAO,MAAM,qBAAqB,GAAI,KAAK,KAAK,KAAG,aAIjD,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const createFieldError = (field) => new Error(`Invalid ${field}`);
|
|
2
|
+
const toNumber = (value, field) => {
|
|
3
|
+
if (typeof value === 'number' && Number.isFinite(value))
|
|
4
|
+
return value;
|
|
5
|
+
if (typeof value === 'bigint') {
|
|
6
|
+
const numeric = Number(value);
|
|
7
|
+
if (Number.isFinite(numeric))
|
|
8
|
+
return numeric;
|
|
9
|
+
}
|
|
10
|
+
throw createFieldError(field);
|
|
11
|
+
};
|
|
12
|
+
export const toSafeInteger = (value, field) => {
|
|
13
|
+
const numeric = toNumber(value, field);
|
|
14
|
+
if (!Number.isSafeInteger(numeric)) {
|
|
15
|
+
throw createFieldError(field);
|
|
16
|
+
}
|
|
17
|
+
return numeric;
|
|
18
|
+
};
|
|
19
|
+
const toString = (value, field) => {
|
|
20
|
+
if (typeof value === 'string')
|
|
21
|
+
return value;
|
|
22
|
+
throw createFieldError(field);
|
|
23
|
+
};
|
|
24
|
+
const toOptionalString = (value, field) => {
|
|
25
|
+
if (value === null || value === undefined)
|
|
26
|
+
return undefined;
|
|
27
|
+
return toString(value, field);
|
|
28
|
+
};
|
|
29
|
+
const toOptionalNumber = (value, field) => {
|
|
30
|
+
if (value === null || value === undefined)
|
|
31
|
+
return undefined;
|
|
32
|
+
return toNumber(value, field);
|
|
33
|
+
};
|
|
34
|
+
export const mapRowToMemory = (row) => ({
|
|
35
|
+
id: toSafeInteger(row.id, 'id'),
|
|
36
|
+
content: toString(row.content, 'content'),
|
|
37
|
+
summary: toOptionalString(row.summary, 'summary'),
|
|
38
|
+
importance: toSafeInteger(row.importance, 'importance'),
|
|
39
|
+
memory_type: toString(row.memory_type, 'memory_type'),
|
|
40
|
+
created_at: toString(row.created_at, 'created_at'),
|
|
41
|
+
accessed_at: toString(row.accessed_at, 'accessed_at'),
|
|
42
|
+
hash: toString(row.hash, 'hash'),
|
|
43
|
+
});
|
|
44
|
+
export const mapRowToSearchResult = (row) => ({
|
|
45
|
+
...mapRowToMemory(row),
|
|
46
|
+
relevance: toOptionalNumber(row.relevance, 'relevance') ?? 0,
|
|
47
|
+
});
|
|
48
|
+
export const mapRowToRelatedMemory = (row) => ({
|
|
49
|
+
...mapRowToMemory(row),
|
|
50
|
+
relation_type: toString(row.relation_type, 'relation_type'),
|
|
51
|
+
depth: toSafeInteger(row.depth, 'depth'),
|
|
52
|
+
});
|
|
53
|
+
//# sourceMappingURL=row-mappers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"row-mappers.js","sourceRoot":"","sources":["../../src/core/row-mappers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-errors.d.ts","sourceRoot":"","sources":["../../src/core/search-errors.ts"],"names":[],"mappings":"AAsCA,eAAO,MAAM,aAAa,GAAI,KAAK,OAAO,KAAG,KAAK,GAAG,SAQpD,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const INDEX_MISSING_TOKENS = [
|
|
2
|
+
'no such module: fts5',
|
|
3
|
+
'no such table: memories_fts',
|
|
4
|
+
];
|
|
5
|
+
const QUERY_INVALID_TOKENS = ['fts5', 'syntax error'];
|
|
6
|
+
const isSearchIndexMissing = (message) => INDEX_MISSING_TOKENS.some((token) => message.includes(token));
|
|
7
|
+
const isSearchQueryInvalid = (message) => QUERY_INVALID_TOKENS.some((token) => message.includes(token));
|
|
8
|
+
const getErrorMessage = (err) => err instanceof Error ? err.message : String(err);
|
|
9
|
+
const SEARCH_ERROR_MAP = [
|
|
10
|
+
{
|
|
11
|
+
matches: isSearchIndexMissing,
|
|
12
|
+
build: () => new Error('Search index unavailable. Ensure FTS5 is enabled and the index is ' +
|
|
13
|
+
'initialized.'),
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
matches: isSearchQueryInvalid,
|
|
17
|
+
build: (message) => new Error('Invalid search query syntax. Check for unbalanced quotes or special ' +
|
|
18
|
+
'characters. ' +
|
|
19
|
+
`Details: ${message}`),
|
|
20
|
+
},
|
|
21
|
+
];
|
|
22
|
+
export const toSearchError = (err) => {
|
|
23
|
+
const message = getErrorMessage(err);
|
|
24
|
+
for (const mapping of SEARCH_ERROR_MAP) {
|
|
25
|
+
if (mapping.matches(message)) {
|
|
26
|
+
return mapping.build(message);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return undefined;
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=search-errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-errors.js","sourceRoot":"","sources":["../../src/core/search-errors.ts"],"names":[],"mappings":"AAAA,MAAM,oBAAoB,GAAG;IAC3B,sBAAsB;IACtB,6BAA6B;CAC9B,CAAC;AACF,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;AAEtD,MAAM,oBAAoB,GAAG,CAAC,OAAe,EAAW,EAAE,CACxD,oBAAoB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;AAEhE,MAAM,oBAAoB,GAAG,CAAC,OAAe,EAAW,EAAE,CACxD,oBAAoB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;AAEhE,MAAM,eAAe,GAAG,CAAC,GAAY,EAAU,EAAE,CAC/C,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAEnD,MAAM,gBAAgB,GAGhB;IACJ;QACE,OAAO,EAAE,oBAAoB;QAC7B,KAAK,EAAE,GAAG,EAAE,CACV,IAAI,KAAK,CACP,oEAAoE;YAClE,cAAc,CACjB;KACJ;IACD;QACE,OAAO,EAAE,oBAAoB;QAC7B,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE,CACjB,IAAI,KAAK,CACP,sEAAsE;YACpE,cAAc;YACd,YAAY,OAAO,EAAE,CACxB;KACJ;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,GAAY,EAAqB,EAAE;IAC/D,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IACrC,KAAK,MAAM,OAAO,IAAI,gBAAgB,EAAE,CAAC;QACvC,IAAI,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7B,OAAO,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { DbRow } from './row-mappers.js';
|
|
2
|
+
export declare const buildSearchQuery: (input: {
|
|
3
|
+
query: string;
|
|
4
|
+
limit: number;
|
|
5
|
+
tags: readonly string[];
|
|
6
|
+
minRelevance?: number;
|
|
7
|
+
offset?: number;
|
|
8
|
+
}) => {
|
|
9
|
+
sql: string;
|
|
10
|
+
params: (number | string)[];
|
|
11
|
+
};
|
|
12
|
+
export declare const executeSearch: (sql: string, params: (number | string)[]) => DbRow[];
|
|
13
|
+
//# 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,KAAK,EAAE,MAAM,kBAAkB,CAAC;AA4E9C,eAAO,MAAM,gBAAgB,GAAI,OAAO;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,KAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAA;CAkB7C,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,KAAK,MAAM,EACX,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,KAC1B,KAAK,EAWP,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { toSearchError } from './search-errors.js';
|
|
2
|
+
import { executeAll, prepareCached } from './sqlite.js';
|
|
3
|
+
const MAX_QUERY_TOKENS = 50;
|
|
4
|
+
const tokenizeQuery = (query) => {
|
|
5
|
+
const parts = query
|
|
6
|
+
.trim()
|
|
7
|
+
.split(/\s+/)
|
|
8
|
+
.filter((w) => w.length > 0);
|
|
9
|
+
if (parts.length === 0)
|
|
10
|
+
return '""';
|
|
11
|
+
if (parts.length > MAX_QUERY_TOKENS) {
|
|
12
|
+
throw new Error('Query has too many terms (max ' + String(MAX_QUERY_TOKENS) + ')');
|
|
13
|
+
}
|
|
14
|
+
const tokens = [];
|
|
15
|
+
for (const part of parts) {
|
|
16
|
+
tokens.push(`"${part.replace(/"/g, '""')}"`);
|
|
17
|
+
}
|
|
18
|
+
return tokens.join(' OR ');
|
|
19
|
+
};
|
|
20
|
+
const buildTagFilter = (tags) => {
|
|
21
|
+
if (tags.length === 0)
|
|
22
|
+
return { clause: '', params: [] };
|
|
23
|
+
const placeholders = tags.map(() => '?').join(', ');
|
|
24
|
+
return {
|
|
25
|
+
clause: ` AND m.id IN (SELECT memory_id FROM tags WHERE tag IN (${placeholders}))`,
|
|
26
|
+
params: [...tags],
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
const buildBaseSql = (whereClause) => {
|
|
30
|
+
const relevanceExpr = '1.0 / (1.0 + abs(bm25(memories_fts)))';
|
|
31
|
+
return `
|
|
32
|
+
WITH ranked AS (
|
|
33
|
+
SELECT m.*, ${relevanceExpr} as relevance
|
|
34
|
+
FROM memories m
|
|
35
|
+
JOIN memories_fts ON m.id = memories_fts.rowid
|
|
36
|
+
WHERE memories_fts MATCH ?${whereClause}
|
|
37
|
+
)
|
|
38
|
+
SELECT * FROM ranked
|
|
39
|
+
`;
|
|
40
|
+
};
|
|
41
|
+
const appendMinRelevance = (input) => {
|
|
42
|
+
if (input.minRelevance === undefined)
|
|
43
|
+
return input;
|
|
44
|
+
return {
|
|
45
|
+
sql: `${input.sql} WHERE relevance >= ?`,
|
|
46
|
+
params: [...input.params, input.minRelevance],
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
const appendPagination = (input) => {
|
|
50
|
+
const params = [...input.params, input.limit];
|
|
51
|
+
let sql = `${input.sql} ORDER BY relevance DESC LIMIT ?`;
|
|
52
|
+
if (input.offset !== undefined && input.offset > 0) {
|
|
53
|
+
sql += ' OFFSET ?';
|
|
54
|
+
params.push(input.offset);
|
|
55
|
+
}
|
|
56
|
+
return { sql, params };
|
|
57
|
+
};
|
|
58
|
+
export const buildSearchQuery = (input) => {
|
|
59
|
+
const sanitizedQuery = tokenizeQuery(input.query);
|
|
60
|
+
const tagFilter = buildTagFilter(input.tags);
|
|
61
|
+
const baseSql = buildBaseSql(tagFilter.clause);
|
|
62
|
+
const baseParams = [sanitizedQuery, ...tagFilter.params];
|
|
63
|
+
const baseQuery = { sql: baseSql, params: baseParams };
|
|
64
|
+
const withRelevance = input.minRelevance === undefined
|
|
65
|
+
? baseQuery
|
|
66
|
+
: appendMinRelevance({
|
|
67
|
+
...baseQuery,
|
|
68
|
+
minRelevance: input.minRelevance,
|
|
69
|
+
});
|
|
70
|
+
const paginatedQuery = input.offset === undefined
|
|
71
|
+
? { ...withRelevance, limit: input.limit }
|
|
72
|
+
: { ...withRelevance, limit: input.limit, offset: input.offset };
|
|
73
|
+
return appendPagination(paginatedQuery);
|
|
74
|
+
};
|
|
75
|
+
export const executeSearch = (sql, params) => {
|
|
76
|
+
try {
|
|
77
|
+
const stmt = prepareCached(sql);
|
|
78
|
+
return executeAll(stmt, ...params);
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
const mappedError = toSearchError(err);
|
|
82
|
+
if (mappedError) {
|
|
83
|
+
throw mappedError;
|
|
84
|
+
}
|
|
85
|
+
throw err;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/core/search.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { StatementSync } from 'node:sqlite';
|
|
2
|
+
import type { DbRow } from './row-mappers.js';
|
|
3
|
+
export type SqlParam = string | number | bigint | null | Uint8Array;
|
|
4
|
+
export declare const prepareCached: (sql: string) => StatementSync;
|
|
5
|
+
export declare const executeAll: (stmt: StatementSync, ...params: SqlParam[]) => DbRow[];
|
|
6
|
+
export declare const executeGet: (stmt: StatementSync, ...params: SqlParam[]) => DbRow | undefined;
|
|
7
|
+
export declare const executeRun: (stmt: StatementSync, ...params: SqlParam[]) => {
|
|
8
|
+
changes: number | bigint;
|
|
9
|
+
};
|
|
10
|
+
export declare const withImmediateTransaction: <T>(operation: () => T) => T;
|
|
11
|
+
//# sourceMappingURL=sqlite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/core/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAE9C,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,UAAU,CAAC;AAqDpE,eAAO,MAAM,aAAa,GAAI,KAAK,MAAM,KAAG,aAW3C,CAAC;AAEF,eAAO,MAAM,UAAU,GACrB,MAAM,aAAa,EACnB,GAAG,QAAQ,QAAQ,EAAE,KACpB,KAAK,EAAuC,CAAC;AAEhD,eAAO,MAAM,UAAU,GACrB,MAAM,aAAa,EACnB,GAAG,QAAQ,QAAQ,EAAE,KACpB,KAAK,GAAG,SAAoD,CAAC;AAEhE,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,CAUhE,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { db } from './database.js';
|
|
2
|
+
const MAX_CACHED_STATEMENTS = 200;
|
|
3
|
+
const statementCache = new Map();
|
|
4
|
+
const statementCacheOrder = [];
|
|
5
|
+
const enforceStatementCacheLimit = () => {
|
|
6
|
+
if (statementCacheOrder.length <= MAX_CACHED_STATEMENTS)
|
|
7
|
+
return;
|
|
8
|
+
const oldestSql = statementCacheOrder.shift();
|
|
9
|
+
if (!oldestSql)
|
|
10
|
+
return;
|
|
11
|
+
const toEvict = statementCache.get(oldestSql);
|
|
12
|
+
statementCache.delete(oldestSql);
|
|
13
|
+
void toEvict;
|
|
14
|
+
};
|
|
15
|
+
const isDbRow = (value) => {
|
|
16
|
+
return typeof value === 'object' && value !== null;
|
|
17
|
+
};
|
|
18
|
+
const toDbRowArray = (value) => {
|
|
19
|
+
if (!Array.isArray(value)) {
|
|
20
|
+
throw new Error('Expected rows array');
|
|
21
|
+
}
|
|
22
|
+
const rows = [];
|
|
23
|
+
for (const row of value) {
|
|
24
|
+
if (!isDbRow(row)) {
|
|
25
|
+
throw new Error('Invalid row');
|
|
26
|
+
}
|
|
27
|
+
rows.push(row);
|
|
28
|
+
}
|
|
29
|
+
return rows;
|
|
30
|
+
};
|
|
31
|
+
const toDbRowOrUndefined = (value) => {
|
|
32
|
+
if (value === undefined)
|
|
33
|
+
return undefined;
|
|
34
|
+
if (!isDbRow(value)) {
|
|
35
|
+
throw new Error('Invalid row');
|
|
36
|
+
}
|
|
37
|
+
return value;
|
|
38
|
+
};
|
|
39
|
+
const toRunResult = (value) => {
|
|
40
|
+
if (typeof value !== 'object' || value === null) {
|
|
41
|
+
throw new Error('Invalid run result');
|
|
42
|
+
}
|
|
43
|
+
const changes = Reflect.get(value, 'changes');
|
|
44
|
+
if (typeof changes !== 'number' && typeof changes !== 'bigint') {
|
|
45
|
+
throw new Error('Invalid run result');
|
|
46
|
+
}
|
|
47
|
+
return { changes };
|
|
48
|
+
};
|
|
49
|
+
export const prepareCached = (sql) => {
|
|
50
|
+
const cached = statementCache.get(sql);
|
|
51
|
+
if (cached)
|
|
52
|
+
return cached;
|
|
53
|
+
const stmt = db.prepare(sql);
|
|
54
|
+
statementCache.set(sql, stmt);
|
|
55
|
+
statementCacheOrder.push(sql);
|
|
56
|
+
enforceStatementCacheLimit();
|
|
57
|
+
return stmt;
|
|
58
|
+
};
|
|
59
|
+
export const executeAll = (stmt, ...params) => toDbRowArray(stmt.all(...params));
|
|
60
|
+
export const executeGet = (stmt, ...params) => toDbRowOrUndefined(stmt.get(...params));
|
|
61
|
+
export const executeRun = (stmt, ...params) => toRunResult(stmt.run(...params));
|
|
62
|
+
export const withImmediateTransaction = (operation) => {
|
|
63
|
+
db.exec('BEGIN IMMEDIATE');
|
|
64
|
+
try {
|
|
65
|
+
const result = operation();
|
|
66
|
+
db.exec('COMMIT');
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
db.exec('ROLLBACK');
|
|
71
|
+
throw err;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
//# sourceMappingURL=sqlite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../src/core/sqlite.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tags.d.ts","sourceRoot":"","sources":["../../src/core/tags.ts"],"names":[],"mappings":"AAwBA,eAAO,MAAM,aAAa,GACxB,MAAM,SAAS,MAAM,EAAE,EACvB,SAAS,MAAM,KACd,MAAM,EAIR,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const validateTag = (tag) => {
|
|
2
|
+
if (tag.length === 0) {
|
|
3
|
+
throw new Error('Tag must be at least 1 character');
|
|
4
|
+
}
|
|
5
|
+
if (tag.length > 50) {
|
|
6
|
+
throw new Error('Tag exceeds 50 characters');
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
const validateTagCount = (tags, maxTags) => {
|
|
10
|
+
if (tags.length > maxTags) {
|
|
11
|
+
throw new Error('Too many tags (max ' + String(maxTags) + ')');
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
const dedupeTags = (tags) => {
|
|
15
|
+
const seen = new Set();
|
|
16
|
+
for (const tag of tags) {
|
|
17
|
+
validateTag(tag);
|
|
18
|
+
seen.add(tag);
|
|
19
|
+
}
|
|
20
|
+
return [...seen];
|
|
21
|
+
};
|
|
22
|
+
export const normalizeTags = (tags, maxTags) => {
|
|
23
|
+
if (tags.length === 0)
|
|
24
|
+
return [];
|
|
25
|
+
validateTagCount(tags, maxTags);
|
|
26
|
+
return dedupeTags(tags);
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=tags.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tags.js","sourceRoot":"","sources":["../../src/core/tags.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,GAAG,CAAC,GAAW,EAAQ,EAAE;IACxC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC;IACD,IAAI,GAAG,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,CAAC,IAAuB,EAAE,OAAe,EAAQ,EAAE;IAC1E,IAAI,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,qBAAqB,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC;IACjE,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,IAAuB,EAAY,EAAE;IACvD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,WAAW,CAAC,GAAG,CAAC,CAAC;QACjB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChB,CAAC;IACD,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;AACnB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,IAAuB,EACvB,OAAe,EACL,EAAE;IACZ,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAChC,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import process from 'node:process';
|
|
4
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
5
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
6
|
+
import { closeDb } from './core/database.js';
|
|
7
|
+
import { registerAllTools } from './tools/index.js';
|
|
8
|
+
import { config } from './utils/config.js';
|
|
9
|
+
import { logger } from './utils/logger.js';
|
|
10
|
+
const packageJsonText = await readFile(new URL('../package.json', import.meta.url), {
|
|
11
|
+
encoding: 'utf-8',
|
|
12
|
+
signal: AbortSignal.timeout(5000),
|
|
13
|
+
});
|
|
14
|
+
const packageVersion = (() => {
|
|
15
|
+
const parsed = JSON.parse(packageJsonText);
|
|
16
|
+
if (typeof parsed !== 'object' || parsed === null)
|
|
17
|
+
return undefined;
|
|
18
|
+
const version = Reflect.get(parsed, 'version');
|
|
19
|
+
return typeof version === 'string' ? version : undefined;
|
|
20
|
+
})();
|
|
21
|
+
const server = new McpServer({ name: 'memdb', version: packageVersion ?? '0.0.0' }, {
|
|
22
|
+
instructions: 'A Memory MCP Server for AI Assistants using node:sqlite',
|
|
23
|
+
capabilities: { logging: {}, tools: {} },
|
|
24
|
+
});
|
|
25
|
+
registerAllTools(server);
|
|
26
|
+
let transport;
|
|
27
|
+
let shuttingDown = false;
|
|
28
|
+
async function shutdown(signal) {
|
|
29
|
+
if (shuttingDown)
|
|
30
|
+
return;
|
|
31
|
+
shuttingDown = true;
|
|
32
|
+
logger.info(`Received ${signal}, shutting down gracefully...`);
|
|
33
|
+
const forceExitTimer = setTimeout(() => {
|
|
34
|
+
logger.warn('Shutdown timeout exceeded, forcing exit');
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}, config.shutdownTimeout);
|
|
37
|
+
const exit = (code) => {
|
|
38
|
+
clearTimeout(forceExitTimer);
|
|
39
|
+
process.exit(code);
|
|
40
|
+
};
|
|
41
|
+
try {
|
|
42
|
+
closeDb();
|
|
43
|
+
if (transport) {
|
|
44
|
+
await transport.close();
|
|
45
|
+
}
|
|
46
|
+
exit(0);
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
logger.error('Error during shutdown:', err);
|
|
50
|
+
exit(1);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async function main() {
|
|
54
|
+
try {
|
|
55
|
+
const stdio = new StdioServerTransport();
|
|
56
|
+
transport = stdio;
|
|
57
|
+
await server.connect(stdio);
|
|
58
|
+
logger.info('Memory MCP Server running on stdio');
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
logger.error('Failed to start server', error);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
void main();
|
|
66
|
+
process.on('SIGTERM', () => void shutdown('SIGTERM'));
|
|
67
|
+
process.on('SIGINT', () => void shutdown('SIGINT'));
|
|
68
|
+
process.on('SIGBREAK', () => void shutdown('SIGBREAK'));
|
|
69
|
+
process.on('uncaughtException', (err, origin) => {
|
|
70
|
+
logger.error(`Uncaught exception (${origin}):`, err);
|
|
71
|
+
process.exit(1);
|
|
72
|
+
});
|
|
73
|
+
process.on('unhandledRejection', (reason) => {
|
|
74
|
+
logger.error('Unhandled rejection:', reason);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
});
|
|
77
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
type ErrorResponse = CallToolResult & {
|
|
3
|
+
content: {
|
|
4
|
+
type: 'text';
|
|
5
|
+
text: string;
|
|
6
|
+
}[];
|
|
7
|
+
structuredContent: {
|
|
8
|
+
ok: false;
|
|
9
|
+
error: {
|
|
10
|
+
code: string;
|
|
11
|
+
message: string;
|
|
12
|
+
};
|
|
13
|
+
result?: unknown;
|
|
14
|
+
};
|
|
15
|
+
isError: true;
|
|
16
|
+
};
|
|
17
|
+
export declare function getErrorMessage(error: unknown): string;
|
|
18
|
+
export declare function createErrorResponse(code: string, message: string, result?: unknown): ErrorResponse;
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEzE,KAAK,aAAa,GAAG,cAAc,GAAG;IACpC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1C,iBAAiB,EAAE;QACjB,EAAE,EAAE,KAAK,CAAC;QACV,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC;QACzC,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,CAAC;IACF,OAAO,EAAE,IAAI,CAAC;CACf,CAAC;AAOF,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAGtD;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,OAAO,GACf,aAAa,CAWf"}
|