@soulcraft/brainy 2.1.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/augmentations/AugmentationMetadataContract.d.ts +94 -0
  2. package/dist/augmentations/AugmentationMetadataContract.js +306 -0
  3. package/dist/augmentations/apiServerAugmentation.d.ts +1 -0
  4. package/dist/augmentations/apiServerAugmentation.js +1 -0
  5. package/dist/augmentations/batchProcessingAugmentation.d.ts +1 -0
  6. package/dist/augmentations/batchProcessingAugmentation.js +1 -0
  7. package/dist/augmentations/brainyAugmentation.d.ts +16 -0
  8. package/dist/augmentations/cacheAugmentation.d.ts +1 -0
  9. package/dist/augmentations/cacheAugmentation.js +1 -0
  10. package/dist/augmentations/conduitAugmentations.d.ts +1 -0
  11. package/dist/augmentations/conduitAugmentations.js +1 -0
  12. package/dist/augmentations/connectionPoolAugmentation.d.ts +1 -0
  13. package/dist/augmentations/connectionPoolAugmentation.js +1 -0
  14. package/dist/augmentations/entityRegistryAugmentation.d.ts +2 -0
  15. package/dist/augmentations/entityRegistryAugmentation.js +2 -0
  16. package/dist/augmentations/indexAugmentation.d.ts +1 -0
  17. package/dist/augmentations/indexAugmentation.js +1 -0
  18. package/dist/augmentations/intelligentVerbScoringAugmentation.d.ts +4 -0
  19. package/dist/augmentations/intelligentVerbScoringAugmentation.js +4 -0
  20. package/dist/augmentations/metadataEnforcer.d.ts +20 -0
  21. package/dist/augmentations/metadataEnforcer.js +171 -0
  22. package/dist/augmentations/metricsAugmentation.d.ts +2 -7
  23. package/dist/augmentations/metricsAugmentation.js +1 -0
  24. package/dist/augmentations/monitoringAugmentation.d.ts +1 -0
  25. package/dist/augmentations/monitoringAugmentation.js +1 -0
  26. package/dist/augmentations/neuralImport.d.ts +4 -0
  27. package/dist/augmentations/neuralImport.js +4 -0
  28. package/dist/augmentations/requestDeduplicatorAugmentation.d.ts +1 -0
  29. package/dist/augmentations/requestDeduplicatorAugmentation.js +1 -0
  30. package/dist/augmentations/serverSearchAugmentations.d.ts +2 -0
  31. package/dist/augmentations/serverSearchAugmentations.js +2 -0
  32. package/dist/augmentations/storageAugmentation.d.ts +1 -0
  33. package/dist/augmentations/storageAugmentation.js +1 -0
  34. package/dist/augmentations/synapseAugmentation.d.ts +4 -0
  35. package/dist/augmentations/synapseAugmentation.js +4 -0
  36. package/dist/augmentations/walAugmentation.d.ts +1 -0
  37. package/dist/augmentations/walAugmentation.js +1 -0
  38. package/dist/brainyData.d.ts +28 -1
  39. package/dist/brainyData.js +229 -83
  40. package/dist/triple/TripleIntelligence.d.ts +4 -0
  41. package/dist/triple/TripleIntelligence.js +39 -9
  42. package/dist/utils/deletedItemsIndex.d.ts +59 -0
  43. package/dist/utils/deletedItemsIndex.js +98 -0
  44. package/dist/utils/ensureDeleted.d.ts +38 -0
  45. package/dist/utils/ensureDeleted.js +79 -0
  46. package/dist/utils/metadataFilter.js +5 -0
  47. package/dist/utils/metadataIndex.d.ts +4 -0
  48. package/dist/utils/metadataIndex.js +45 -0
  49. package/dist/utils/metadataNamespace.d.ts +113 -0
  50. package/dist/utils/metadataNamespace.js +162 -0
  51. package/dist/utils/periodicCleanup.d.ts +87 -0
  52. package/dist/utils/periodicCleanup.js +219 -0
  53. package/package.json +9 -3
@@ -0,0 +1,219 @@
1
+ /**
2
+ * Periodic Cleanup for Soft-Deleted Items
3
+ *
4
+ * SAFETY-FIRST APPROACH:
5
+ * - Maintains durability guarantees (storage-first)
6
+ * - Coordinates HNSW and metadata index consistency
7
+ * - Isolated from live operations
8
+ * - Graceful failure handling
9
+ */
10
+ import { prodLog } from './logger.js';
11
+ import { isDeleted } from './metadataNamespace.js';
12
+ /**
13
+ * Coordinates safe cleanup of old soft-deleted items across all indexes
14
+ *
15
+ * CRITICAL SAFETY FEATURES:
16
+ * 1. Storage-first deletion (durability)
17
+ * 2. Index consistency coordination
18
+ * 3. Batch processing with limits
19
+ * 4. Error isolation and recovery
20
+ */
21
+ export class PeriodicCleanup {
22
+ constructor(storage, hnswIndex, metadataIndex, config = {}) {
23
+ this.cleanupTimer = null;
24
+ this.running = false;
25
+ this.storage = storage;
26
+ this.hnswIndex = hnswIndex;
27
+ this.metadataIndex = metadataIndex;
28
+ // Default: clean up items deleted more than 1 hour ago
29
+ this.config = {
30
+ maxAge: config.maxAge ?? 60 * 60 * 1000, // 1 hour
31
+ batchSize: config.batchSize ?? 100, // 100 items max per batch
32
+ cleanupInterval: config.cleanupInterval ?? 15 * 60 * 1000, // Every 15 minutes
33
+ enabled: config.enabled ?? true
34
+ };
35
+ this.stats = {
36
+ itemsProcessed: 0,
37
+ itemsDeleted: 0,
38
+ errors: 0,
39
+ lastRun: 0,
40
+ nextRun: 0
41
+ };
42
+ }
43
+ /**
44
+ * Start periodic cleanup
45
+ */
46
+ start() {
47
+ if (!this.config.enabled || this.cleanupTimer) {
48
+ return;
49
+ }
50
+ prodLog.info(`Starting periodic cleanup: maxAge=${this.config.maxAge}, batchSize=${this.config.batchSize}, interval=${this.config.cleanupInterval}`);
51
+ this.scheduleNext();
52
+ }
53
+ /**
54
+ * Stop periodic cleanup
55
+ */
56
+ stop() {
57
+ if (this.cleanupTimer) {
58
+ clearTimeout(this.cleanupTimer);
59
+ this.cleanupTimer = null;
60
+ }
61
+ prodLog.info('Stopped periodic cleanup');
62
+ }
63
+ /**
64
+ * Run cleanup manually
65
+ */
66
+ async runNow() {
67
+ if (this.running) {
68
+ throw new Error('Cleanup already running');
69
+ }
70
+ return this.performCleanup();
71
+ }
72
+ /**
73
+ * Get current cleanup statistics
74
+ */
75
+ getStats() {
76
+ return { ...this.stats };
77
+ }
78
+ scheduleNext() {
79
+ const nextRun = Date.now() + this.config.cleanupInterval;
80
+ this.stats.nextRun = nextRun;
81
+ this.cleanupTimer = setTimeout(async () => {
82
+ await this.performCleanup();
83
+ this.scheduleNext();
84
+ }, this.config.cleanupInterval);
85
+ }
86
+ /**
87
+ * CRITICAL: Coordinated cleanup across all indexes
88
+ *
89
+ * SAFETY PROTOCOL:
90
+ * 1. Find eligible items (old + soft-deleted)
91
+ * 2. Remove from storage FIRST (durability)
92
+ * 3. Remove from HNSW (graph consistency)
93
+ * 4. Remove from metadata index (search consistency)
94
+ * 5. Track stats and errors
95
+ */
96
+ async performCleanup() {
97
+ if (this.running) {
98
+ prodLog.warn('Cleanup already running, skipping');
99
+ return this.stats;
100
+ }
101
+ this.running = true;
102
+ const startTime = Date.now();
103
+ this.stats.lastRun = startTime;
104
+ try {
105
+ prodLog.debug(`Starting cleanup run: maxAge=${this.config.maxAge}, cutoffTime=${startTime - this.config.maxAge}`);
106
+ // Step 1: Find eligible items for cleanup
107
+ const eligibleItems = await this.findEligibleItems(startTime);
108
+ if (eligibleItems.length === 0) {
109
+ prodLog.debug('No items eligible for cleanup');
110
+ return this.stats;
111
+ }
112
+ prodLog.info(`Found ${eligibleItems.length} items eligible for cleanup`);
113
+ // Step 2: Process in batches for safety
114
+ let processed = 0;
115
+ let deleted = 0;
116
+ let errors = 0;
117
+ for (let i = 0; i < eligibleItems.length; i += this.config.batchSize) {
118
+ const batch = eligibleItems.slice(i, i + this.config.batchSize);
119
+ const batchResult = await this.processBatch(batch);
120
+ processed += batchResult.processed;
121
+ deleted += batchResult.deleted;
122
+ errors += batchResult.errors;
123
+ // Small delay between batches to avoid overwhelming the system
124
+ if (i + this.config.batchSize < eligibleItems.length) {
125
+ await new Promise(resolve => setTimeout(resolve, 10));
126
+ }
127
+ }
128
+ // Update stats
129
+ this.stats.itemsProcessed += processed;
130
+ this.stats.itemsDeleted += deleted;
131
+ this.stats.errors += errors;
132
+ prodLog.info(`Cleanup run completed: processed=${processed}, deleted=${deleted}, errors=${errors}, duration=${Date.now() - startTime}ms`);
133
+ }
134
+ catch (error) {
135
+ prodLog.error(`Cleanup run failed: ${error}`);
136
+ this.stats.errors++;
137
+ }
138
+ finally {
139
+ this.running = false;
140
+ }
141
+ return this.stats;
142
+ }
143
+ /**
144
+ * Find items eligible for cleanup (old + soft-deleted)
145
+ */
146
+ async findEligibleItems(currentTime) {
147
+ const cutoffTime = currentTime - this.config.maxAge;
148
+ const eligibleItems = [];
149
+ try {
150
+ // Get all nouns from storage (using pagination to avoid memory issues)
151
+ const nounsResult = await this.storage.getNouns({
152
+ pagination: { limit: 1000 } // Process in chunks
153
+ });
154
+ for (const noun of nounsResult.items) {
155
+ try {
156
+ if (!noun.metadata || !isDeleted(noun.metadata)) {
157
+ continue; // Not deleted, skip
158
+ }
159
+ // Check if old enough for cleanup
160
+ const deletedTime = noun.metadata._brainy?.updated || 0;
161
+ if (deletedTime && (currentTime - deletedTime) > this.config.maxAge) {
162
+ eligibleItems.push(noun.id);
163
+ }
164
+ }
165
+ catch (error) {
166
+ prodLog.warn(`Failed to check item ${noun.id} for cleanup eligibility: ${error}`);
167
+ }
168
+ }
169
+ }
170
+ catch (error) {
171
+ prodLog.error(`Failed to find eligible items: ${error}`);
172
+ throw error;
173
+ }
174
+ return eligibleItems;
175
+ }
176
+ /**
177
+ * Process a batch of items for cleanup
178
+ *
179
+ * CRITICAL: This maintains the durability-first approach:
180
+ * Storage → HNSW → Metadata Index
181
+ */
182
+ async processBatch(itemIds) {
183
+ let processed = 0;
184
+ let deleted = 0;
185
+ let errors = 0;
186
+ for (const id of itemIds) {
187
+ processed++;
188
+ try {
189
+ // STEP 1: Remove from storage FIRST (durability guarantee)
190
+ try {
191
+ await this.storage.deleteNoun(id);
192
+ }
193
+ catch (storageError) {
194
+ prodLog.warn(`Failed to delete ${id} from storage: ${storageError}`);
195
+ errors++;
196
+ continue;
197
+ }
198
+ // STEP 2: Remove from HNSW index (vector search consistency)
199
+ const hnswResult = this.hnswIndex.removeItem(id);
200
+ if (!hnswResult) {
201
+ prodLog.warn(`Failed to remove ${id} from HNSW index (may not have been indexed)`);
202
+ // Not a critical error - item might not have been in vector index
203
+ }
204
+ // STEP 3: Remove from metadata index (faceted search consistency)
205
+ if (this.metadataIndex) {
206
+ await this.metadataIndex.removeFromIndex(id);
207
+ }
208
+ deleted++;
209
+ prodLog.debug(`Successfully cleaned up item ${id}`);
210
+ }
211
+ catch (error) {
212
+ errors++;
213
+ prodLog.error(`Failed to cleanup item ${id}: ${error}`);
214
+ }
215
+ }
216
+ return { processed, deleted, errors };
217
+ }
218
+ }
219
+ //# sourceMappingURL=periodicCleanup.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soulcraft/brainy",
3
- "version": "2.1.0",
3
+ "version": "2.3.0",
4
4
  "description": "Universal Knowledge Protocol™ - World's first Triple Intelligence database unifying vector, graph, and document search in one API. 31 nouns × 40 verbs for infinite expressiveness.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -77,7 +77,12 @@
77
77
  "lint": "eslint --ext .ts,.js src/",
78
78
  "lint:fix": "eslint --ext .ts,.js src/ --fix",
79
79
  "format": "prettier --write \"src/**/*.{ts,js}\"",
80
- "format:check": "prettier --check \"src/**/*.{ts,js}\""
80
+ "format:check": "prettier --check \"src/**/*.{ts,js}\"",
81
+ "release": "standard-version",
82
+ "release:patch": "standard-version --release-as patch",
83
+ "release:minor": "standard-version --release-as minor",
84
+ "release:major": "standard-version --release-as major",
85
+ "release:dry": "standard-version --dry-run"
81
86
  },
82
87
  "keywords": [
83
88
  "ai-database",
@@ -130,13 +135,14 @@
130
135
  "@typescript-eslint/eslint-plugin": "^8.0.0",
131
136
  "@typescript-eslint/parser": "^8.0.0",
132
137
  "@vitest/coverage-v8": "^3.2.4",
138
+ "standard-version": "^9.5.0",
133
139
  "tsx": "^4.19.2",
134
140
  "typescript": "^5.4.5",
135
141
  "vitest": "^3.2.4"
136
142
  },
137
143
  "dependencies": {
138
144
  "@aws-sdk/client-s3": "^3.540.0",
139
- "@huggingface/transformers": "^3.1.0",
145
+ "@huggingface/transformers": "^3.7.2",
140
146
  "boxen": "^8.0.1",
141
147
  "chalk": "^5.3.0",
142
148
  "cli-table3": "^0.6.5",