@soulcraft/brainy 0.48.0 → 0.50.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 (47) hide show
  1. package/README.md +304 -555
  2. package/dist/brainyData.d.ts +83 -2
  3. package/dist/brainyData.js +536 -66
  4. package/dist/brainyData.js.map +1 -1
  5. package/dist/coreTypes.d.ts +74 -12
  6. package/dist/distributed/configManager.d.ts +9 -0
  7. package/dist/distributed/configManager.js +129 -10
  8. package/dist/distributed/configManager.js.map +1 -1
  9. package/dist/hnsw/hnswIndex.d.ts +1 -1
  10. package/dist/hnsw/hnswIndex.js +44 -25
  11. package/dist/hnsw/hnswIndex.js.map +1 -1
  12. package/dist/hnsw/optimizedHNSWIndex.d.ts +1 -1
  13. package/dist/hnsw/optimizedHNSWIndex.js +3 -3
  14. package/dist/hnsw/optimizedHNSWIndex.js.map +1 -1
  15. package/dist/storage/adapters/baseStorageAdapter.d.ts +18 -2
  16. package/dist/storage/adapters/baseStorageAdapter.js +69 -4
  17. package/dist/storage/adapters/baseStorageAdapter.js.map +1 -1
  18. package/dist/storage/adapters/fileSystemStorage.d.ts +14 -8
  19. package/dist/storage/adapters/fileSystemStorage.js +90 -22
  20. package/dist/storage/adapters/fileSystemStorage.js.map +1 -1
  21. package/dist/storage/adapters/memoryStorage.d.ts +0 -8
  22. package/dist/storage/adapters/memoryStorage.js +26 -45
  23. package/dist/storage/adapters/memoryStorage.js.map +1 -1
  24. package/dist/storage/adapters/opfsStorage.d.ts +40 -8
  25. package/dist/storage/adapters/opfsStorage.js +195 -44
  26. package/dist/storage/adapters/opfsStorage.js.map +1 -1
  27. package/dist/storage/adapters/optimizedS3Search.js +4 -3
  28. package/dist/storage/adapters/optimizedS3Search.js.map +1 -1
  29. package/dist/storage/adapters/s3CompatibleStorage.d.ts +3 -10
  30. package/dist/storage/adapters/s3CompatibleStorage.js +41 -44
  31. package/dist/storage/adapters/s3CompatibleStorage.js.map +1 -1
  32. package/dist/storage/backwardCompatibility.d.ts +84 -0
  33. package/dist/storage/backwardCompatibility.js +141 -0
  34. package/dist/storage/backwardCompatibility.js.map +1 -0
  35. package/dist/storage/baseStorage.d.ts +33 -19
  36. package/dist/storage/baseStorage.js +116 -195
  37. package/dist/storage/baseStorage.js.map +1 -1
  38. package/dist/utils/metadataFilter.d.ts +79 -0
  39. package/dist/utils/metadataFilter.js +229 -0
  40. package/dist/utils/metadataFilter.js.map +1 -0
  41. package/dist/utils/metadataIndex.d.ts +148 -0
  42. package/dist/utils/metadataIndex.js +639 -0
  43. package/dist/utils/metadataIndex.js.map +1 -0
  44. package/dist/utils/metadataIndexCache.d.ts +60 -0
  45. package/dist/utils/metadataIndexCache.js +119 -0
  46. package/dist/utils/metadataIndexCache.js.map +1 -0
  47. package/package.json +1 -1
@@ -0,0 +1,229 @@
1
+ /**
2
+ * Smart metadata filtering for vector search
3
+ * Filters DURING search to ensure relevant results
4
+ * Simple API that just works without configuration
5
+ */
6
+ /**
7
+ * Check if a value matches a query with operators
8
+ */
9
+ function matchesQuery(value, query) {
10
+ // Direct equality check
11
+ if (typeof query !== 'object' || query === null || Array.isArray(query)) {
12
+ return value === query;
13
+ }
14
+ // Check for MongoDB-style operators
15
+ for (const [op, operand] of Object.entries(query)) {
16
+ switch (op) {
17
+ case '$eq':
18
+ if (value !== operand)
19
+ return false;
20
+ break;
21
+ case '$ne':
22
+ if (value === operand)
23
+ return false;
24
+ break;
25
+ case '$gt':
26
+ if (typeof value !== 'number' || typeof operand !== 'number' || !(value > operand))
27
+ return false;
28
+ break;
29
+ case '$gte':
30
+ if (typeof value !== 'number' || typeof operand !== 'number' || !(value >= operand))
31
+ return false;
32
+ break;
33
+ case '$lt':
34
+ if (typeof value !== 'number' || typeof operand !== 'number' || !(value < operand))
35
+ return false;
36
+ break;
37
+ case '$lte':
38
+ if (typeof value !== 'number' || typeof operand !== 'number' || !(value <= operand))
39
+ return false;
40
+ break;
41
+ case '$in':
42
+ if (!Array.isArray(operand) || !operand.includes(value))
43
+ return false;
44
+ break;
45
+ case '$nin':
46
+ if (!Array.isArray(operand) || operand.includes(value))
47
+ return false;
48
+ break;
49
+ case '$exists':
50
+ if ((value !== undefined) !== operand)
51
+ return false;
52
+ break;
53
+ case '$regex':
54
+ const regex = typeof operand === 'string' ? new RegExp(operand) : operand;
55
+ if (!(regex instanceof RegExp) || !regex.test(String(value)))
56
+ return false;
57
+ break;
58
+ case '$includes':
59
+ if (!Array.isArray(value) || !value.includes(operand))
60
+ return false;
61
+ break;
62
+ case '$all':
63
+ if (!Array.isArray(value) || !Array.isArray(operand))
64
+ return false;
65
+ for (const item of operand) {
66
+ if (!value.includes(item))
67
+ return false;
68
+ }
69
+ break;
70
+ case '$size':
71
+ if (!Array.isArray(value) || value.length !== operand)
72
+ return false;
73
+ break;
74
+ default:
75
+ // Unknown operator, treat as field name
76
+ if (!matchesFieldQuery(value, op, operand))
77
+ return false;
78
+ }
79
+ }
80
+ return true;
81
+ }
82
+ /**
83
+ * Check if a field matches a query
84
+ */
85
+ function matchesFieldQuery(obj, field, query) {
86
+ const value = getNestedValue(obj, field);
87
+ return matchesQuery(value, query);
88
+ }
89
+ /**
90
+ * Get nested value from object using dot notation
91
+ */
92
+ function getNestedValue(obj, path) {
93
+ const parts = path.split('.');
94
+ let current = obj;
95
+ for (const part of parts) {
96
+ if (current === null || current === undefined) {
97
+ return undefined;
98
+ }
99
+ current = current[part];
100
+ }
101
+ return current;
102
+ }
103
+ /**
104
+ * Check if metadata matches the filter
105
+ */
106
+ export function matchesMetadataFilter(metadata, filter) {
107
+ if (!filter || Object.keys(filter).length === 0) {
108
+ return true;
109
+ }
110
+ for (const [key, query] of Object.entries(filter)) {
111
+ // Handle logical operators
112
+ if (key === '$and') {
113
+ if (!Array.isArray(query))
114
+ return false;
115
+ for (const subFilter of query) {
116
+ if (!matchesMetadataFilter(metadata, subFilter))
117
+ return false;
118
+ }
119
+ continue;
120
+ }
121
+ if (key === '$or') {
122
+ if (!Array.isArray(query))
123
+ return false;
124
+ let matched = false;
125
+ for (const subFilter of query) {
126
+ if (matchesMetadataFilter(metadata, subFilter)) {
127
+ matched = true;
128
+ break;
129
+ }
130
+ }
131
+ if (!matched)
132
+ return false;
133
+ continue;
134
+ }
135
+ if (key === '$not') {
136
+ if (matchesMetadataFilter(metadata, query))
137
+ return false;
138
+ continue;
139
+ }
140
+ // Handle field queries
141
+ const value = getNestedValue(metadata, key);
142
+ if (!matchesQuery(value, query)) {
143
+ return false;
144
+ }
145
+ }
146
+ return true;
147
+ }
148
+ /**
149
+ * Calculate metadata boost score
150
+ */
151
+ export function calculateMetadataScore(metadata, filter, scoring) {
152
+ if (!scoring || !scoring.metadataBoosts) {
153
+ return 0;
154
+ }
155
+ let score = 0;
156
+ for (const [field, boost] of Object.entries(scoring.metadataBoosts)) {
157
+ const value = getNestedValue(metadata, field);
158
+ if (typeof boost === 'function') {
159
+ score += boost(value, filter);
160
+ }
161
+ else if (value !== undefined) {
162
+ // Check if the field matches the filter
163
+ const fieldFilter = filter[field];
164
+ if (fieldFilter && matchesQuery(value, fieldFilter)) {
165
+ score += boost;
166
+ }
167
+ }
168
+ }
169
+ return score;
170
+ }
171
+ /**
172
+ * Apply compound scoring to search results
173
+ */
174
+ export function applyCompoundScoring(results, filter, scoring) {
175
+ if (!scoring || (!scoring.vectorWeight && !scoring.metadataWeight)) {
176
+ return results;
177
+ }
178
+ const vectorWeight = scoring.vectorWeight ?? 1.0;
179
+ const metadataWeight = scoring.metadataWeight ?? 0.0;
180
+ return results.map(result => {
181
+ const metadataScore = calculateMetadataScore(result.metadata, filter, scoring);
182
+ const combinedScore = (result.score * vectorWeight) + (metadataScore * metadataWeight);
183
+ return {
184
+ ...result,
185
+ score: combinedScore
186
+ };
187
+ }).sort((a, b) => b.score - a.score); // Re-sort by combined score
188
+ }
189
+ /**
190
+ * Filter search results by metadata
191
+ */
192
+ export function filterSearchResultsByMetadata(results, filter) {
193
+ if (!filter || Object.keys(filter).length === 0) {
194
+ return results;
195
+ }
196
+ return results.filter(result => matchesMetadataFilter(result.metadata, filter));
197
+ }
198
+ /**
199
+ * Filter nouns by metadata before search
200
+ */
201
+ export function filterNounsByMetadata(nouns, filter) {
202
+ if (!filter || Object.keys(filter).length === 0) {
203
+ return nouns;
204
+ }
205
+ return nouns.filter(noun => matchesMetadataFilter(noun.metadata, filter));
206
+ }
207
+ export function aggregateSearchResults(results, facets) {
208
+ const facetResults = {};
209
+ for (const [facetName, config] of Object.entries(facets)) {
210
+ const counts = {};
211
+ for (const result of results) {
212
+ const value = getNestedValue(result.metadata, config.field);
213
+ if (value !== undefined) {
214
+ const key = String(value);
215
+ counts[key] = (counts[key] || 0) + 1;
216
+ }
217
+ }
218
+ // Sort by count and apply limit
219
+ const sorted = Object.entries(counts)
220
+ .sort((a, b) => b[1] - a[1])
221
+ .slice(0, config.limit || 10);
222
+ facetResults[facetName] = Object.fromEntries(sorted);
223
+ }
224
+ return {
225
+ results,
226
+ facets: facetResults
227
+ };
228
+ }
229
+ //# sourceMappingURL=metadataFilter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadataFilter.js","sourceRoot":"","sources":["../../src/utils/metadataFilter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA6CH;;GAEG;AACH,SAAS,YAAY,CAAC,KAAU,EAAE,KAAU;IAC1C,wBAAwB;IACxB,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACxE,OAAO,KAAK,KAAK,KAAK,CAAA;IACxB,CAAC;IAED,oCAAoC;IACpC,KAAK,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAClD,QAAQ,EAAE,EAAE,CAAC;YACX,KAAK,KAAK;gBACR,IAAI,KAAK,KAAK,OAAO;oBAAE,OAAO,KAAK,CAAA;gBACnC,MAAK;YACP,KAAK,KAAK;gBACR,IAAI,KAAK,KAAK,OAAO;oBAAE,OAAO,KAAK,CAAA;gBACnC,MAAK;YACP,KAAK,KAAK;gBACR,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,KAAK,GAAG,OAAO,CAAC;oBAAE,OAAO,KAAK,CAAA;gBAChG,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,KAAK,IAAI,OAAO,CAAC;oBAAE,OAAO,KAAK,CAAA;gBACjG,MAAK;YACP,KAAK,KAAK;gBACR,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,KAAK,GAAG,OAAO,CAAC;oBAAE,OAAO,KAAK,CAAA;gBAChG,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,KAAK,IAAI,OAAO,CAAC;oBAAE,OAAO,KAAK,CAAA;gBACjG,MAAK;YACP,KAAK,KAAK;gBACR,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;oBAAE,OAAO,KAAK,CAAA;gBACrE,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;oBAAE,OAAO,KAAK,CAAA;gBACpE,MAAK;YACP,KAAK,SAAS;gBACZ,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,KAAK,OAAO;oBAAE,OAAO,KAAK,CAAA;gBACnD,MAAK;YACP,KAAK,QAAQ;gBACX,MAAM,KAAK,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAiB,CAAA;gBACnF,IAAI,CAAC,CAAC,KAAK,YAAY,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oBAAE,OAAO,KAAK,CAAA;gBAC1E,MAAK;YACP,KAAK,WAAW;gBACd,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC;oBAAE,OAAO,KAAK,CAAA;gBACnE,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;oBAAE,OAAO,KAAK,CAAA;gBAClE,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;oBAC3B,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;wBAAE,OAAO,KAAK,CAAA;gBACzC,CAAC;gBACD,MAAK;YACP,KAAK,OAAO;gBACV,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,OAAO;oBAAE,OAAO,KAAK,CAAA;gBACnE,MAAK;YACP;gBACE,wCAAwC;gBACxC,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,EAAE,EAAE,OAAO,CAAC;oBAAE,OAAO,KAAK,CAAA;QAC5D,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,GAAQ,EAAE,KAAa,EAAE,KAAU;IAC5D,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IACxC,OAAO,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;AACnC,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,GAAQ,EAAE,IAAY;IAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC7B,IAAI,OAAO,GAAG,GAAG,CAAA;IAEjB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC9C,OAAO,SAAS,CAAA;QAClB,CAAC;QACD,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACzB,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAa,EAAE,MAAsB;IACzE,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,2BAA2B;QAC3B,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;YACnB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;gBAAE,OAAO,KAAK,CAAA;YACvC,KAAK,MAAM,SAAS,IAAI,KAAK,EAAE,CAAC;gBAC9B,IAAI,CAAC,qBAAqB,CAAC,QAAQ,EAAE,SAAS,CAAC;oBAAE,OAAO,KAAK,CAAA;YAC/D,CAAC;YACD,SAAQ;QACV,CAAC;QAED,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;YAClB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;gBAAE,OAAO,KAAK,CAAA;YACvC,IAAI,OAAO,GAAG,KAAK,CAAA;YACnB,KAAK,MAAM,SAAS,IAAI,KAAK,EAAE,CAAC;gBAC9B,IAAI,qBAAqB,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,CAAC;oBAC/C,OAAO,GAAG,IAAI,CAAA;oBACd,MAAK;gBACP,CAAC;YACH,CAAC;YACD,IAAI,CAAC,OAAO;gBAAE,OAAO,KAAK,CAAA;YAC1B,SAAQ;QACV,CAAC;QAED,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;YACnB,IAAI,qBAAqB,CAAC,QAAQ,EAAE,KAAK,CAAC;gBAAE,OAAO,KAAK,CAAA;YACxD,SAAQ;QACV,CAAC;QAED,uBAAuB;QACvB,MAAM,KAAK,GAAG,cAAc,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;QAC3C,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC;YAChC,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CACpC,QAAa,EACb,MAAsB,EACtB,OAA0C;IAE1C,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;QACxC,OAAO,CAAC,CAAA;IACV,CAAC;IAED,IAAI,KAAK,GAAG,CAAC,CAAA;IAEb,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;QACpE,MAAM,KAAK,GAAG,cAAc,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;QAE7C,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;YAChC,KAAK,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QAC/B,CAAC;aAAM,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAC/B,wCAAwC;YACxC,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;YACjC,IAAI,WAAW,IAAI,YAAY,CAAC,KAAK,EAAE,WAAW,CAAC,EAAE,CAAC;gBACpD,KAAK,IAAI,KAAK,CAAA;YAChB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAClC,OAA0B,EAC1B,MAAsB,EACtB,OAA0C;IAE1C,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,YAAY,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;QACnE,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,GAAG,CAAA;IAChD,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,GAAG,CAAA;IAEpD,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;QAC1B,MAAM,aAAa,GAAG,sBAAsB,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;QAC9E,MAAM,aAAa,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,aAAa,GAAG,cAAc,CAAC,CAAA;QAEtF,OAAO;YACL,GAAG,MAAM;YACT,KAAK,EAAE,aAAa;SACrB,CAAA;IACH,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAA,CAAC,4BAA4B;AACnE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,6BAA6B,CAC3C,OAA0B,EAC1B,MAAsB;IAEtB,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChD,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,OAAO,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAC7B,qBAAqB,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAC/C,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACnC,KAAiB,EACjB,MAAsB;IAEtB,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChD,OAAO,KAAK,CAAA;IACd,CAAC;IAED,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CACzB,qBAAqB,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAC7C,CAAA;AACH,CAAC;AAmBD,MAAM,UAAU,sBAAsB,CACpC,OAA0B,EAC1B,MAAmC;IAEnC,MAAM,YAAY,GAAgC,EAAE,CAAA;IAEpD,KAAK,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACzD,MAAM,MAAM,GAA2B,EAAE,CAAA;QAEzC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,KAAK,GAAG,cAAc,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,CAAA;YAE3D,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;gBACzB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;YACtC,CAAC;QACH,CAAC;QAED,gCAAgC;QAChC,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;aAClC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;aAC3B,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAA;QAE/B,YAAY,CAAC,SAAS,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;IACtD,CAAC;IAED,OAAO;QACL,OAAO;QACP,MAAM,EAAE,YAAY;KACrB,CAAA;AACH,CAAC"}
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Metadata Index System
3
+ * Maintains inverted indexes for fast metadata filtering
4
+ * Automatically updates indexes when data changes
5
+ */
6
+ import { StorageAdapter } from '../coreTypes.js';
7
+ export interface MetadataIndexEntry {
8
+ field: string;
9
+ value: string | number | boolean;
10
+ ids: Set<string>;
11
+ lastUpdated: number;
12
+ }
13
+ export interface FieldIndexData {
14
+ values: Record<string, number>;
15
+ lastUpdated: number;
16
+ }
17
+ export interface MetadataIndexStats {
18
+ totalEntries: number;
19
+ totalIds: number;
20
+ fieldsIndexed: string[];
21
+ lastRebuild: number;
22
+ indexSize: number;
23
+ }
24
+ export interface MetadataIndexConfig {
25
+ maxIndexSize?: number;
26
+ rebuildThreshold?: number;
27
+ autoOptimize?: boolean;
28
+ indexedFields?: string[];
29
+ excludeFields?: string[];
30
+ }
31
+ /**
32
+ * Manages metadata indexes for fast filtering
33
+ * Maintains inverted indexes: field+value -> list of IDs
34
+ */
35
+ export declare class MetadataIndexManager {
36
+ private storage;
37
+ private config;
38
+ private indexCache;
39
+ private dirtyEntries;
40
+ private isRebuilding;
41
+ private metadataCache;
42
+ private fieldIndexes;
43
+ private dirtyFields;
44
+ private lastFlushTime;
45
+ private autoFlushThreshold;
46
+ constructor(storage: StorageAdapter, config?: MetadataIndexConfig);
47
+ /**
48
+ * Get index key for field and value
49
+ */
50
+ private getIndexKey;
51
+ /**
52
+ * Generate field index filename for filter discovery
53
+ */
54
+ private getFieldIndexFilename;
55
+ /**
56
+ * Generate value chunk filename for scalable storage
57
+ */
58
+ private getValueChunkFilename;
59
+ /**
60
+ * Make a value safe for use in filenames
61
+ */
62
+ private makeSafeFilename;
63
+ /**
64
+ * Normalize value for consistent indexing
65
+ */
66
+ private normalizeValue;
67
+ /**
68
+ * Create a short hash for long values to avoid filesystem filename limits
69
+ */
70
+ private hashValue;
71
+ /**
72
+ * Check if field should be indexed
73
+ */
74
+ private shouldIndexField;
75
+ /**
76
+ * Extract indexable field-value pairs from metadata
77
+ */
78
+ private extractIndexableFields;
79
+ /**
80
+ * Add item to metadata indexes
81
+ */
82
+ addToIndex(id: string, metadata: any, skipFlush?: boolean): Promise<void>;
83
+ /**
84
+ * Update field index with value count
85
+ */
86
+ private updateFieldIndex;
87
+ /**
88
+ * Remove item from metadata indexes
89
+ */
90
+ removeFromIndex(id: string, metadata?: any): Promise<void>;
91
+ /**
92
+ * Get IDs for a specific field-value combination with caching
93
+ */
94
+ getIds(field: string, value: any): Promise<string[]>;
95
+ /**
96
+ * Get all available values for a field (for filter discovery)
97
+ */
98
+ getFilterValues(field: string): Promise<string[]>;
99
+ /**
100
+ * Get all indexed fields (for filter discovery)
101
+ */
102
+ getFilterFields(): Promise<string[]>;
103
+ /**
104
+ * Convert MongoDB-style filter to simple field-value criteria for indexing
105
+ */
106
+ private convertFilterToCriteria;
107
+ /**
108
+ * Get IDs matching MongoDB-style metadata filter using indexes where possible
109
+ */
110
+ getIdsForFilter(filter: any): Promise<string[]>;
111
+ /**
112
+ * Get IDs matching multiple criteria (intersection) - LEGACY METHOD
113
+ * @deprecated Use getIdsForFilter instead
114
+ */
115
+ getIdsForCriteria(criteria: Record<string, any>): Promise<string[]>;
116
+ /**
117
+ * Flush dirty entries to storage
118
+ */
119
+ flush(): Promise<void>;
120
+ /**
121
+ * Load field index from storage
122
+ */
123
+ private loadFieldIndex;
124
+ /**
125
+ * Save field index to storage
126
+ */
127
+ private saveFieldIndex;
128
+ /**
129
+ * Get index statistics
130
+ */
131
+ getStats(): Promise<MetadataIndexStats>;
132
+ /**
133
+ * Rebuild entire index from scratch using pagination
134
+ */
135
+ rebuild(): Promise<void>;
136
+ /**
137
+ * Load index entry from storage using safe filenames
138
+ */
139
+ private loadIndexEntry;
140
+ /**
141
+ * Save index entry to storage using safe filenames
142
+ */
143
+ private saveIndexEntry;
144
+ /**
145
+ * Delete index entry from storage using safe filenames
146
+ */
147
+ private deleteIndexEntry;
148
+ }