@soulcraft/brainy 2.15.0 → 3.0.1

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 (204) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +249 -152
  3. package/dist/api/ConfigAPI.d.ts +67 -0
  4. package/dist/api/ConfigAPI.js +166 -0
  5. package/dist/api/DataAPI.d.ts +123 -0
  6. package/dist/api/DataAPI.js +391 -0
  7. package/dist/api/SecurityAPI.d.ts +50 -0
  8. package/dist/api/SecurityAPI.js +139 -0
  9. package/dist/api/UniversalImportAPI.d.ts +134 -0
  10. package/dist/api/UniversalImportAPI.js +615 -0
  11. package/dist/augmentationManager.js +12 -7
  12. package/dist/augmentationPipeline.d.ts +0 -61
  13. package/dist/augmentationPipeline.js +0 -87
  14. package/dist/augmentationRegistry.d.ts +1 -1
  15. package/dist/augmentationRegistry.js +1 -1
  16. package/dist/augmentations/apiServerAugmentation.d.ts +27 -1
  17. package/dist/augmentations/apiServerAugmentation.js +288 -7
  18. package/dist/augmentations/auditLogAugmentation.d.ts +109 -0
  19. package/dist/augmentations/auditLogAugmentation.js +358 -0
  20. package/dist/augmentations/batchProcessingAugmentation.d.ts +3 -2
  21. package/dist/augmentations/batchProcessingAugmentation.js +123 -22
  22. package/dist/augmentations/brainyAugmentation.d.ts +87 -8
  23. package/dist/augmentations/brainyAugmentation.js +159 -2
  24. package/dist/augmentations/cacheAugmentation.d.ts +6 -5
  25. package/dist/augmentations/cacheAugmentation.js +113 -17
  26. package/dist/augmentations/conduitAugmentations.d.ts +2 -2
  27. package/dist/augmentations/conduitAugmentations.js +2 -2
  28. package/dist/augmentations/configResolver.d.ts +122 -0
  29. package/dist/augmentations/configResolver.js +440 -0
  30. package/dist/augmentations/connectionPoolAugmentation.d.ts +3 -1
  31. package/dist/augmentations/connectionPoolAugmentation.js +37 -12
  32. package/dist/augmentations/defaultAugmentations.d.ts +9 -11
  33. package/dist/augmentations/defaultAugmentations.js +4 -11
  34. package/dist/augmentations/discovery/catalogDiscovery.d.ts +142 -0
  35. package/dist/augmentations/discovery/catalogDiscovery.js +249 -0
  36. package/dist/augmentations/discovery/localDiscovery.d.ts +84 -0
  37. package/dist/augmentations/discovery/localDiscovery.js +246 -0
  38. package/dist/augmentations/discovery/runtimeLoader.d.ts +97 -0
  39. package/dist/augmentations/discovery/runtimeLoader.js +337 -0
  40. package/dist/augmentations/discovery.d.ts +152 -0
  41. package/dist/augmentations/discovery.js +441 -0
  42. package/dist/augmentations/display/intelligentComputation.d.ts +1 -1
  43. package/dist/augmentations/display/intelligentComputation.js +4 -4
  44. package/dist/augmentations/entityRegistryAugmentation.d.ts +3 -1
  45. package/dist/augmentations/entityRegistryAugmentation.js +5 -1
  46. package/dist/augmentations/indexAugmentation.d.ts +3 -3
  47. package/dist/augmentations/indexAugmentation.js +2 -2
  48. package/dist/augmentations/intelligentVerbScoringAugmentation.d.ts +22 -6
  49. package/dist/augmentations/intelligentVerbScoringAugmentation.js +106 -23
  50. package/dist/augmentations/manifest.d.ts +176 -0
  51. package/dist/augmentations/manifest.js +8 -0
  52. package/dist/augmentations/marketplace/AugmentationMarketplace.d.ts +168 -0
  53. package/dist/augmentations/marketplace/AugmentationMarketplace.js +329 -0
  54. package/dist/augmentations/marketplace/cli.d.ts +47 -0
  55. package/dist/augmentations/marketplace/cli.js +265 -0
  56. package/dist/augmentations/metricsAugmentation.d.ts +3 -3
  57. package/dist/augmentations/metricsAugmentation.js +2 -2
  58. package/dist/augmentations/monitoringAugmentation.d.ts +3 -3
  59. package/dist/augmentations/monitoringAugmentation.js +2 -2
  60. package/dist/augmentations/neuralImport.d.ts +1 -1
  61. package/dist/augmentations/rateLimitAugmentation.d.ts +82 -0
  62. package/dist/augmentations/rateLimitAugmentation.js +321 -0
  63. package/dist/augmentations/requestDeduplicatorAugmentation.d.ts +2 -2
  64. package/dist/augmentations/requestDeduplicatorAugmentation.js +1 -1
  65. package/dist/augmentations/storageAugmentation.d.ts +1 -1
  66. package/dist/augmentations/storageAugmentation.js +2 -2
  67. package/dist/augmentations/storageAugmentations.d.ts +37 -8
  68. package/dist/augmentations/storageAugmentations.js +204 -15
  69. package/dist/augmentations/synapseAugmentation.d.ts +1 -1
  70. package/dist/augmentations/synapseAugmentation.js +35 -16
  71. package/dist/augmentations/typeMatching/intelligentTypeMatcher.d.ts +39 -59
  72. package/dist/augmentations/typeMatching/intelligentTypeMatcher.js +103 -389
  73. package/dist/augmentations/universalDisplayAugmentation.d.ts +2 -2
  74. package/dist/augmentations/universalDisplayAugmentation.js +2 -2
  75. package/dist/brainy-unified.d.ts +106 -0
  76. package/dist/brainy-unified.js +327 -0
  77. package/dist/brainy.d.ts +273 -0
  78. package/dist/brainy.js +1181 -0
  79. package/dist/brainyData.d.ts +29 -72
  80. package/dist/brainyData.js +350 -304
  81. package/dist/brainyDataV3.d.ts +186 -0
  82. package/dist/brainyDataV3.js +337 -0
  83. package/dist/browserFramework.d.ts +6 -6
  84. package/dist/browserFramework.js +11 -8
  85. package/dist/browserFramework.minimal.d.ts +5 -5
  86. package/dist/browserFramework.minimal.js +11 -8
  87. package/dist/config/index.d.ts +2 -2
  88. package/dist/config/index.js +3 -3
  89. package/dist/config/modelAutoConfig.d.ts +6 -7
  90. package/dist/config/modelAutoConfig.js +17 -76
  91. package/dist/cortex/backupRestore.d.ts +2 -2
  92. package/dist/cortex/backupRestore.js +85 -27
  93. package/dist/cortex/healthCheck.d.ts +2 -2
  94. package/dist/cortex/neuralImport.d.ts +2 -2
  95. package/dist/cortex/neuralImport.js +18 -13
  96. package/dist/cortex/performanceMonitor.d.ts +2 -2
  97. package/dist/critical/model-guardian.d.ts +4 -0
  98. package/dist/critical/model-guardian.js +31 -11
  99. package/dist/demo.d.ts +4 -4
  100. package/dist/demo.js +7 -7
  101. package/dist/distributed/cacheSync.d.ts +112 -0
  102. package/dist/distributed/cacheSync.js +265 -0
  103. package/dist/distributed/coordinator.d.ts +193 -0
  104. package/dist/distributed/coordinator.js +548 -0
  105. package/dist/distributed/httpTransport.d.ts +120 -0
  106. package/dist/distributed/httpTransport.js +446 -0
  107. package/dist/distributed/index.d.ts +8 -0
  108. package/dist/distributed/index.js +5 -0
  109. package/dist/distributed/networkTransport.d.ts +132 -0
  110. package/dist/distributed/networkTransport.js +633 -0
  111. package/dist/distributed/queryPlanner.d.ts +104 -0
  112. package/dist/distributed/queryPlanner.js +327 -0
  113. package/dist/distributed/readWriteSeparation.d.ts +134 -0
  114. package/dist/distributed/readWriteSeparation.js +350 -0
  115. package/dist/distributed/shardManager.d.ts +114 -0
  116. package/dist/distributed/shardManager.js +357 -0
  117. package/dist/distributed/shardMigration.d.ts +110 -0
  118. package/dist/distributed/shardMigration.js +289 -0
  119. package/dist/distributed/storageDiscovery.d.ts +160 -0
  120. package/dist/distributed/storageDiscovery.js +551 -0
  121. package/dist/embeddings/EmbeddingManager.d.ts +0 -4
  122. package/dist/embeddings/EmbeddingManager.js +21 -26
  123. package/dist/errors/brainyError.d.ts +5 -1
  124. package/dist/errors/brainyError.js +12 -0
  125. package/dist/examples/basicUsage.js +3 -3
  126. package/dist/graph/graphAdjacencyIndex.d.ts +96 -0
  127. package/dist/graph/graphAdjacencyIndex.js +288 -0
  128. package/dist/graph/pathfinding.js +4 -2
  129. package/dist/hnsw/scaledHNSWSystem.js +11 -2
  130. package/dist/importManager.js +6 -3
  131. package/dist/index.d.ts +12 -21
  132. package/dist/index.js +14 -22
  133. package/dist/mcp/brainyMCPAdapter.d.ts +4 -4
  134. package/dist/mcp/brainyMCPAdapter.js +5 -5
  135. package/dist/mcp/brainyMCPService.d.ts +3 -3
  136. package/dist/mcp/brainyMCPService.js +3 -11
  137. package/dist/mcp/mcpAugmentationToolset.js +20 -30
  138. package/dist/neural/embeddedPatterns.d.ts +1 -1
  139. package/dist/neural/embeddedPatterns.js +2 -2
  140. package/dist/neural/entityExtractor.d.ts +65 -0
  141. package/dist/neural/entityExtractor.js +316 -0
  142. package/dist/neural/improvedNeuralAPI.js +90 -79
  143. package/dist/neural/naturalLanguageProcessor.d.ts +155 -10
  144. package/dist/neural/naturalLanguageProcessor.js +941 -66
  145. package/dist/neural/naturalLanguageProcessorStatic.d.ts +2 -2
  146. package/dist/neural/naturalLanguageProcessorStatic.js +3 -3
  147. package/dist/neural/neuralAPI.js +8 -2
  148. package/dist/neural/patternLibrary.d.ts +57 -3
  149. package/dist/neural/patternLibrary.js +348 -13
  150. package/dist/neural/staticPatternMatcher.d.ts +2 -2
  151. package/dist/neural/staticPatternMatcher.js +2 -2
  152. package/dist/shared/default-augmentations.d.ts +3 -3
  153. package/dist/shared/default-augmentations.js +5 -5
  154. package/dist/storage/adapters/fileSystemStorage.d.ts +4 -0
  155. package/dist/storage/adapters/fileSystemStorage.js +54 -1
  156. package/dist/storage/adapters/memoryStorage.js +13 -8
  157. package/dist/storage/backwardCompatibility.d.ts +10 -78
  158. package/dist/storage/backwardCompatibility.js +17 -132
  159. package/dist/storage/baseStorage.d.ts +6 -0
  160. package/dist/storage/baseStorage.js +17 -0
  161. package/dist/storage/cacheManager.js +2 -2
  162. package/dist/storage/readOnlyOptimizations.js +8 -3
  163. package/dist/streaming/pipeline.d.ts +154 -0
  164. package/dist/streaming/pipeline.js +551 -0
  165. package/dist/triple/TripleIntelligence.d.ts +25 -110
  166. package/dist/triple/TripleIntelligence.js +4 -574
  167. package/dist/triple/TripleIntelligenceSystem.d.ts +159 -0
  168. package/dist/triple/TripleIntelligenceSystem.js +519 -0
  169. package/dist/types/apiTypes.d.ts +278 -0
  170. package/dist/types/apiTypes.js +33 -0
  171. package/dist/types/brainy.types.d.ts +308 -0
  172. package/dist/types/brainy.types.js +8 -0
  173. package/dist/types/brainyDataInterface.d.ts +3 -3
  174. package/dist/types/brainyDataInterface.js +2 -2
  175. package/dist/types/graphTypes.js +2 -2
  176. package/dist/utils/cacheAutoConfig.d.ts +3 -3
  177. package/dist/utils/embedding.js +8 -14
  178. package/dist/utils/enhancedLogger.d.ts +104 -0
  179. package/dist/utils/enhancedLogger.js +232 -0
  180. package/dist/utils/index.d.ts +1 -1
  181. package/dist/utils/index.js +1 -1
  182. package/dist/utils/intelligentTypeMapper.d.ts +60 -0
  183. package/dist/utils/intelligentTypeMapper.js +349 -0
  184. package/dist/utils/metadataIndex.d.ts +118 -1
  185. package/dist/utils/metadataIndex.js +539 -16
  186. package/dist/utils/paramValidation.d.ts +39 -0
  187. package/dist/utils/paramValidation.js +192 -0
  188. package/dist/utils/rateLimiter.d.ts +160 -0
  189. package/dist/utils/rateLimiter.js +271 -0
  190. package/dist/utils/statistics.d.ts +4 -4
  191. package/dist/utils/statistics.js +3 -3
  192. package/dist/utils/structuredLogger.d.ts +146 -0
  193. package/dist/utils/structuredLogger.js +394 -0
  194. package/dist/utils/textEncoding.js +2 -1
  195. package/dist/utils/typeValidation.d.ts +34 -0
  196. package/dist/utils/typeValidation.js +247 -0
  197. package/package.json +14 -6
  198. package/scripts/download-models.cjs +6 -15
  199. package/dist/augmentations/walAugmentation.d.ts +0 -111
  200. package/dist/augmentations/walAugmentation.js +0 -519
  201. package/dist/chat/BrainyChat.d.ts +0 -121
  202. package/dist/chat/BrainyChat.js +0 -396
  203. package/dist/chat/ChatCLI.d.ts +0 -61
  204. package/dist/chat/ChatCLI.js +0 -351
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Zero-Config Parameter Validation
3
+ *
4
+ * Self-configuring validation that adapts to system capabilities
5
+ * Only enforces universal truths, learns everything else
6
+ */
7
+ import { NounType, VerbType } from '../types/graphTypes.js';
8
+ import * as os from 'os';
9
+ /**
10
+ * Auto-configured limits based on system resources
11
+ * These adapt to available memory and observed performance
12
+ */
13
+ class ValidationConfig {
14
+ constructor() {
15
+ // Performance observations
16
+ this.avgQueryTime = 0;
17
+ this.queryCount = 0;
18
+ // Auto-configure based on system resources
19
+ const totalMemory = os.totalmem();
20
+ const availableMemory = os.freemem();
21
+ // Scale limits based on available memory
22
+ // 1GB = 10K limit, 8GB = 80K limit, etc.
23
+ this.maxLimit = Math.min(100000, // Absolute max for safety
24
+ Math.floor(availableMemory / (1024 * 1024 * 100)) * 1000);
25
+ // Query length scales with memory too
26
+ this.maxQueryLength = Math.min(50000, Math.floor(availableMemory / (1024 * 1024 * 10)) * 1000);
27
+ // Vector dimensions (standard for all-MiniLM-L6-v2)
28
+ this.maxVectorDimensions = 384;
29
+ }
30
+ static getInstance() {
31
+ if (!ValidationConfig.instance) {
32
+ ValidationConfig.instance = new ValidationConfig();
33
+ }
34
+ return ValidationConfig.instance;
35
+ }
36
+ /**
37
+ * Learn from actual usage to adjust limits
38
+ */
39
+ recordQuery(duration, resultCount) {
40
+ this.queryCount++;
41
+ this.avgQueryTime = (this.avgQueryTime * (this.queryCount - 1) + duration) / this.queryCount;
42
+ // If queries are consistently fast with large results, increase limits
43
+ if (this.avgQueryTime < 100 && resultCount > this.maxLimit * 0.8) {
44
+ this.maxLimit = Math.min(this.maxLimit * 1.5, 100000);
45
+ }
46
+ // If queries are slow, reduce limits
47
+ if (this.avgQueryTime > 1000) {
48
+ this.maxLimit = Math.max(this.maxLimit * 0.8, 1000);
49
+ }
50
+ }
51
+ }
52
+ /**
53
+ * Universal validations - things that are always invalid
54
+ * These are mathematical/logical truths, not configuration
55
+ */
56
+ export function validateFindParams(params) {
57
+ const config = ValidationConfig.getInstance();
58
+ // Universal truth: negative pagination never makes sense
59
+ if (params.limit !== undefined) {
60
+ if (params.limit < 0) {
61
+ throw new Error('limit must be non-negative');
62
+ }
63
+ if (params.limit > config.maxLimit) {
64
+ throw new Error(`limit exceeds auto-configured maximum of ${config.maxLimit} (based on available memory)`);
65
+ }
66
+ }
67
+ if (params.offset !== undefined && params.offset < 0) {
68
+ throw new Error('offset must be non-negative');
69
+ }
70
+ // Universal truth: probability/similarity must be 0-1
71
+ if (params.near?.threshold !== undefined) {
72
+ const t = params.near.threshold;
73
+ if (t < 0 || t > 1) {
74
+ throw new Error('threshold must be between 0 and 1');
75
+ }
76
+ }
77
+ // Universal truth: can't specify both query and vector (they're alternatives)
78
+ if (params.query !== undefined && params.vector !== undefined) {
79
+ throw new Error('cannot specify both query and vector - they are mutually exclusive');
80
+ }
81
+ // Universal truth: can't use both cursor and offset pagination
82
+ if (params.cursor !== undefined && params.offset !== undefined) {
83
+ throw new Error('cannot use both cursor and offset pagination simultaneously');
84
+ }
85
+ // Auto-limit query length based on memory
86
+ if (params.query && params.query.length > config.maxQueryLength) {
87
+ throw new Error(`query exceeds auto-configured maximum length of ${config.maxQueryLength} characters`);
88
+ }
89
+ // Validate vector dimensions if provided
90
+ if (params.vector && params.vector.length !== config.maxVectorDimensions) {
91
+ throw new Error(`vector must have exactly ${config.maxVectorDimensions} dimensions`);
92
+ }
93
+ // Validate enum types if specified
94
+ if (params.type) {
95
+ const types = Array.isArray(params.type) ? params.type : [params.type];
96
+ for (const type of types) {
97
+ if (!Object.values(NounType).includes(type)) {
98
+ throw new Error(`invalid NounType: ${type}`);
99
+ }
100
+ }
101
+ }
102
+ }
103
+ /**
104
+ * Validate add parameters
105
+ */
106
+ export function validateAddParams(params) {
107
+ // Universal truth: must have data or vector
108
+ if (!params.data && !params.vector) {
109
+ throw new Error('must provide either data or vector');
110
+ }
111
+ // Validate noun type
112
+ if (!Object.values(NounType).includes(params.type)) {
113
+ throw new Error(`invalid NounType: ${params.type}`);
114
+ }
115
+ // Validate vector dimensions if provided
116
+ if (params.vector) {
117
+ const config = ValidationConfig.getInstance();
118
+ if (params.vector.length !== config.maxVectorDimensions) {
119
+ throw new Error(`vector must have exactly ${config.maxVectorDimensions} dimensions`);
120
+ }
121
+ }
122
+ }
123
+ /**
124
+ * Validate update parameters
125
+ */
126
+ export function validateUpdateParams(params) {
127
+ // Universal truth: must have an ID
128
+ if (!params.id) {
129
+ throw new Error('id is required for update');
130
+ }
131
+ // Universal truth: must update something
132
+ if (!params.data && !params.metadata && !params.type && !params.vector) {
133
+ throw new Error('must specify at least one field to update');
134
+ }
135
+ // Validate type if changing
136
+ if (params.type && !Object.values(NounType).includes(params.type)) {
137
+ throw new Error(`invalid NounType: ${params.type}`);
138
+ }
139
+ // Validate vector dimensions if provided
140
+ if (params.vector) {
141
+ const config = ValidationConfig.getInstance();
142
+ if (params.vector.length !== config.maxVectorDimensions) {
143
+ throw new Error(`vector must have exactly ${config.maxVectorDimensions} dimensions`);
144
+ }
145
+ }
146
+ }
147
+ /**
148
+ * Validate relate parameters
149
+ */
150
+ export function validateRelateParams(params) {
151
+ // Universal truths
152
+ if (!params.from) {
153
+ throw new Error('from entity ID is required');
154
+ }
155
+ if (!params.to) {
156
+ throw new Error('to entity ID is required');
157
+ }
158
+ if (params.from === params.to) {
159
+ throw new Error('cannot create self-referential relationship');
160
+ }
161
+ // Validate verb type
162
+ if (!Object.values(VerbType).includes(params.type)) {
163
+ throw new Error(`invalid VerbType: ${params.type}`);
164
+ }
165
+ // Universal truth: weight must be 0-1
166
+ if (params.weight !== undefined) {
167
+ if (params.weight < 0 || params.weight > 1) {
168
+ throw new Error('weight must be between 0 and 1');
169
+ }
170
+ }
171
+ }
172
+ /**
173
+ * Get current validation configuration
174
+ * Useful for debugging and monitoring
175
+ */
176
+ export function getValidationConfig() {
177
+ const config = ValidationConfig.getInstance();
178
+ return {
179
+ maxLimit: config.maxLimit,
180
+ maxQueryLength: config.maxQueryLength,
181
+ maxVectorDimensions: config.maxVectorDimensions,
182
+ systemMemory: os.totalmem(),
183
+ availableMemory: os.freemem()
184
+ };
185
+ }
186
+ /**
187
+ * Record query performance for auto-tuning
188
+ */
189
+ export function recordQueryPerformance(duration, resultCount) {
190
+ ValidationConfig.getInstance().recordQuery(duration, resultCount);
191
+ }
192
+ //# sourceMappingURL=paramValidation.js.map
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Rate Limiter for Brainy API
3
+ *
4
+ * Provides rate limiting without external dependencies like Redis.
5
+ * - Uses in-memory storage for single instances
6
+ * - Can use S3/R2 for distributed rate limiting
7
+ *
8
+ * @module rateLimiter
9
+ */
10
+ import { BaseStorageAdapter } from '../storage/adapters/baseStorageAdapter.js';
11
+ export interface RateLimitConfig {
12
+ /**
13
+ * Maximum number of requests allowed
14
+ */
15
+ maxRequests: number;
16
+ /**
17
+ * Time window in milliseconds
18
+ */
19
+ windowMs: number;
20
+ /**
21
+ * Optional message to return when rate limit is exceeded
22
+ */
23
+ message?: string;
24
+ /**
25
+ * Whether to use distributed storage (S3/R2) for rate limiting
26
+ */
27
+ distributed?: boolean;
28
+ /**
29
+ * Storage adapter for distributed rate limiting
30
+ */
31
+ storage?: BaseStorageAdapter;
32
+ /**
33
+ * Key prefix for distributed storage
34
+ */
35
+ keyPrefix?: string;
36
+ }
37
+ export interface RateLimitResult {
38
+ /**
39
+ * Whether the request is allowed
40
+ */
41
+ allowed: boolean;
42
+ /**
43
+ * Number of requests remaining in the current window
44
+ */
45
+ remaining: number;
46
+ /**
47
+ * Time when the rate limit window resets (Unix timestamp)
48
+ */
49
+ resetTime: number;
50
+ /**
51
+ * Total limit for the window
52
+ */
53
+ limit: number;
54
+ }
55
+ /**
56
+ * Simple in-memory rate limiter
57
+ */
58
+ export declare class RateLimiter {
59
+ private config;
60
+ private requests;
61
+ private cleanupInterval;
62
+ constructor(config: RateLimitConfig);
63
+ /**
64
+ * Check if a request is allowed and update the rate limit
65
+ */
66
+ checkLimit(identifier: string): Promise<RateLimitResult>;
67
+ /**
68
+ * Check rate limit using in-memory storage
69
+ */
70
+ private checkMemoryLimit;
71
+ /**
72
+ * Check rate limit using distributed storage (S3/R2)
73
+ */
74
+ private checkDistributedLimit;
75
+ /**
76
+ * Reset rate limit for a specific identifier
77
+ */
78
+ reset(identifier: string): Promise<void>;
79
+ /**
80
+ * Start cleanup interval to remove expired entries
81
+ */
82
+ private startCleanup;
83
+ /**
84
+ * Stop the rate limiter and cleanup
85
+ */
86
+ destroy(): void;
87
+ }
88
+ /**
89
+ * Express/Connect middleware for rate limiting
90
+ */
91
+ export declare function rateLimitMiddleware(config: RateLimitConfig): (req: any, res: any, next: any) => Promise<void>;
92
+ /**
93
+ * Create a rate limiter for use with Brainy
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * // For single instance (in-memory)
98
+ * const limiter = createRateLimiter({
99
+ * maxRequests: 100,
100
+ * windowMs: 15 * 60 * 1000 // 15 minutes
101
+ * })
102
+ *
103
+ * // For distributed (using S3/R2)
104
+ * const limiter = createRateLimiter({
105
+ * maxRequests: 100,
106
+ * windowMs: 15 * 60 * 1000,
107
+ * distributed: true,
108
+ * storage: myS3Adapter
109
+ * })
110
+ *
111
+ * // Check rate limit
112
+ * const result = await limiter.checkLimit('user-123')
113
+ * if (!result.allowed) {
114
+ * throw new Error('Rate limit exceeded')
115
+ * }
116
+ * ```
117
+ */
118
+ export declare function createRateLimiter(config: RateLimitConfig): RateLimiter;
119
+ /**
120
+ * Preset configurations for common use cases
121
+ */
122
+ export declare const RateLimitPresets: {
123
+ /**
124
+ * Default API rate limit: 100 requests per 15 minutes
125
+ */
126
+ default: {
127
+ maxRequests: number;
128
+ windowMs: number;
129
+ };
130
+ /**
131
+ * Strict rate limit: 10 requests per minute
132
+ */
133
+ strict: {
134
+ maxRequests: number;
135
+ windowMs: number;
136
+ };
137
+ /**
138
+ * Lenient rate limit: 1000 requests per hour
139
+ */
140
+ lenient: {
141
+ maxRequests: number;
142
+ windowMs: number;
143
+ };
144
+ /**
145
+ * Search endpoint: 30 requests per minute
146
+ */
147
+ search: {
148
+ maxRequests: number;
149
+ windowMs: number;
150
+ message: string;
151
+ };
152
+ /**
153
+ * Write operations: 20 requests per minute
154
+ */
155
+ write: {
156
+ maxRequests: number;
157
+ windowMs: number;
158
+ message: string;
159
+ };
160
+ };
@@ -0,0 +1,271 @@
1
+ /**
2
+ * Rate Limiter for Brainy API
3
+ *
4
+ * Provides rate limiting without external dependencies like Redis.
5
+ * - Uses in-memory storage for single instances
6
+ * - Can use S3/R2 for distributed rate limiting
7
+ *
8
+ * @module rateLimiter
9
+ */
10
+ /**
11
+ * Simple in-memory rate limiter
12
+ */
13
+ export class RateLimiter {
14
+ constructor(config) {
15
+ this.config = config;
16
+ this.requests = new Map();
17
+ this.cleanupInterval = null;
18
+ // Start cleanup interval to remove expired entries
19
+ this.startCleanup();
20
+ }
21
+ /**
22
+ * Check if a request is allowed and update the rate limit
23
+ */
24
+ async checkLimit(identifier) {
25
+ const now = Date.now();
26
+ if (this.config.distributed && this.config.storage) {
27
+ return this.checkDistributedLimit(identifier, now);
28
+ }
29
+ return this.checkMemoryLimit(identifier, now);
30
+ }
31
+ /**
32
+ * Check rate limit using in-memory storage
33
+ */
34
+ checkMemoryLimit(identifier, now) {
35
+ const entry = this.requests.get(identifier);
36
+ const resetTime = now + this.config.windowMs;
37
+ if (!entry || entry.resetTime <= now) {
38
+ // New window or expired window
39
+ this.requests.set(identifier, {
40
+ count: 1,
41
+ resetTime
42
+ });
43
+ return {
44
+ allowed: true,
45
+ remaining: this.config.maxRequests - 1,
46
+ resetTime,
47
+ limit: this.config.maxRequests
48
+ };
49
+ }
50
+ // Existing window
51
+ if (entry.count < this.config.maxRequests) {
52
+ entry.count++;
53
+ return {
54
+ allowed: true,
55
+ remaining: this.config.maxRequests - entry.count,
56
+ resetTime: entry.resetTime,
57
+ limit: this.config.maxRequests
58
+ };
59
+ }
60
+ // Rate limit exceeded
61
+ return {
62
+ allowed: false,
63
+ remaining: 0,
64
+ resetTime: entry.resetTime,
65
+ limit: this.config.maxRequests
66
+ };
67
+ }
68
+ /**
69
+ * Check rate limit using distributed storage (S3/R2)
70
+ */
71
+ async checkDistributedLimit(identifier, now) {
72
+ const storage = this.config.storage;
73
+ const key = `ratelimit_${identifier}`;
74
+ const resetTime = now + this.config.windowMs;
75
+ try {
76
+ // Try to get existing rate limit data from metadata storage
77
+ const existing = await storage.getMetadata(key);
78
+ if (!existing || !existing.resetTime ||
79
+ Number(existing.resetTime) <= now) {
80
+ // New window or expired window
81
+ await storage.saveMetadata(key, {
82
+ count: 1,
83
+ resetTime: resetTime,
84
+ identifier
85
+ });
86
+ return {
87
+ allowed: true,
88
+ remaining: this.config.maxRequests - 1,
89
+ resetTime,
90
+ limit: this.config.maxRequests
91
+ };
92
+ }
93
+ const count = Number(existing.count || 0);
94
+ if (count < this.config.maxRequests) {
95
+ // Update count
96
+ await storage.saveMetadata(key, {
97
+ count: count + 1,
98
+ resetTime: existing.resetTime,
99
+ identifier
100
+ });
101
+ return {
102
+ allowed: true,
103
+ remaining: this.config.maxRequests - count - 1,
104
+ resetTime: Number(existing.resetTime),
105
+ limit: this.config.maxRequests
106
+ };
107
+ }
108
+ // Rate limit exceeded
109
+ return {
110
+ allowed: false,
111
+ remaining: 0,
112
+ resetTime: Number(existing.resetTime),
113
+ limit: this.config.maxRequests
114
+ };
115
+ }
116
+ catch (error) {
117
+ // On error, fail open (allow the request)
118
+ console.warn('Rate limiter error, failing open:', error);
119
+ return {
120
+ allowed: true,
121
+ remaining: this.config.maxRequests,
122
+ resetTime,
123
+ limit: this.config.maxRequests
124
+ };
125
+ }
126
+ }
127
+ /**
128
+ * Reset rate limit for a specific identifier
129
+ */
130
+ async reset(identifier) {
131
+ if (this.config.distributed && this.config.storage) {
132
+ const key = `ratelimit_${identifier}`;
133
+ // Reset by setting count to 0 and expired time
134
+ await this.config.storage.saveMetadata(key, {
135
+ count: 0,
136
+ resetTime: 0,
137
+ identifier
138
+ });
139
+ }
140
+ else {
141
+ this.requests.delete(identifier);
142
+ }
143
+ }
144
+ /**
145
+ * Start cleanup interval to remove expired entries
146
+ */
147
+ startCleanup() {
148
+ // Run cleanup every minute
149
+ this.cleanupInterval = setInterval(() => {
150
+ const now = Date.now();
151
+ const expired = [];
152
+ for (const [key, entry] of this.requests) {
153
+ if (entry.resetTime <= now) {
154
+ expired.push(key);
155
+ }
156
+ }
157
+ for (const key of expired) {
158
+ this.requests.delete(key);
159
+ }
160
+ }, 60000); // 1 minute
161
+ // Don't keep Node.js process alive just for cleanup
162
+ if (this.cleanupInterval.unref) {
163
+ this.cleanupInterval.unref();
164
+ }
165
+ }
166
+ /**
167
+ * Stop the rate limiter and cleanup
168
+ */
169
+ destroy() {
170
+ if (this.cleanupInterval) {
171
+ clearInterval(this.cleanupInterval);
172
+ this.cleanupInterval = null;
173
+ }
174
+ this.requests.clear();
175
+ }
176
+ }
177
+ /**
178
+ * Express/Connect middleware for rate limiting
179
+ */
180
+ export function rateLimitMiddleware(config) {
181
+ const limiter = new RateLimiter(config);
182
+ return async (req, res, next) => {
183
+ // Use IP address as identifier (can be customized)
184
+ const identifier = req.ip || req.connection?.remoteAddress || 'unknown';
185
+ const result = await limiter.checkLimit(identifier);
186
+ // Set rate limit headers
187
+ res.setHeader('X-RateLimit-Limit', result.limit);
188
+ res.setHeader('X-RateLimit-Remaining', result.remaining);
189
+ res.setHeader('X-RateLimit-Reset', result.resetTime);
190
+ if (!result.allowed) {
191
+ res.status(429).json({
192
+ error: config.message || 'Too many requests, please try again later.',
193
+ retryAfter: Math.ceil((result.resetTime - Date.now()) / 1000)
194
+ });
195
+ return;
196
+ }
197
+ next();
198
+ };
199
+ }
200
+ /**
201
+ * Create a rate limiter for use with Brainy
202
+ *
203
+ * @example
204
+ * ```typescript
205
+ * // For single instance (in-memory)
206
+ * const limiter = createRateLimiter({
207
+ * maxRequests: 100,
208
+ * windowMs: 15 * 60 * 1000 // 15 minutes
209
+ * })
210
+ *
211
+ * // For distributed (using S3/R2)
212
+ * const limiter = createRateLimiter({
213
+ * maxRequests: 100,
214
+ * windowMs: 15 * 60 * 1000,
215
+ * distributed: true,
216
+ * storage: myS3Adapter
217
+ * })
218
+ *
219
+ * // Check rate limit
220
+ * const result = await limiter.checkLimit('user-123')
221
+ * if (!result.allowed) {
222
+ * throw new Error('Rate limit exceeded')
223
+ * }
224
+ * ```
225
+ */
226
+ export function createRateLimiter(config) {
227
+ return new RateLimiter(config);
228
+ }
229
+ /**
230
+ * Preset configurations for common use cases
231
+ */
232
+ export const RateLimitPresets = {
233
+ /**
234
+ * Default API rate limit: 100 requests per 15 minutes
235
+ */
236
+ default: {
237
+ maxRequests: 100,
238
+ windowMs: 15 * 60 * 1000
239
+ },
240
+ /**
241
+ * Strict rate limit: 10 requests per minute
242
+ */
243
+ strict: {
244
+ maxRequests: 10,
245
+ windowMs: 60 * 1000
246
+ },
247
+ /**
248
+ * Lenient rate limit: 1000 requests per hour
249
+ */
250
+ lenient: {
251
+ maxRequests: 1000,
252
+ windowMs: 60 * 60 * 1000
253
+ },
254
+ /**
255
+ * Search endpoint: 30 requests per minute
256
+ */
257
+ search: {
258
+ maxRequests: 30,
259
+ windowMs: 60 * 1000,
260
+ message: 'Search rate limit exceeded. Please wait before searching again.'
261
+ },
262
+ /**
263
+ * Write operations: 20 requests per minute
264
+ */
265
+ write: {
266
+ maxRequests: 20,
267
+ windowMs: 60 * 1000,
268
+ message: 'Write rate limit exceeded. Please slow down your write operations.'
269
+ }
270
+ };
271
+ //# sourceMappingURL=rateLimiter.js.map
@@ -1,17 +1,17 @@
1
1
  /**
2
2
  * Utility functions for retrieving statistics from Brainy
3
3
  */
4
- import { BrainyData } from '../brainyData.js';
4
+ import { Brainy } from '../brainy.js';
5
5
  /**
6
- * Get statistics about the current state of a BrainyData instance
6
+ * Get statistics about the current state of a Brainy instance
7
7
  * This function provides access to statistics at the root level of the library
8
8
  *
9
- * @param instance A BrainyData instance to get statistics from
9
+ * @param instance A Brainy instance to get statistics from
10
10
  * @param options Additional options for retrieving statistics
11
11
  * @returns Object containing counts of nouns, verbs, metadata entries, and HNSW index size
12
12
  * @throws Error if the instance is not provided or if statistics retrieval fails
13
13
  */
14
- export declare function getStatistics(instance: BrainyData, options?: {
14
+ export declare function getStatistics(instance: Brainy, options?: {
15
15
  service?: string | string[];
16
16
  }): Promise<{
17
17
  nounCount: number;
@@ -2,17 +2,17 @@
2
2
  * Utility functions for retrieving statistics from Brainy
3
3
  */
4
4
  /**
5
- * Get statistics about the current state of a BrainyData instance
5
+ * Get statistics about the current state of a Brainy instance
6
6
  * This function provides access to statistics at the root level of the library
7
7
  *
8
- * @param instance A BrainyData instance to get statistics from
8
+ * @param instance A Brainy instance to get statistics from
9
9
  * @param options Additional options for retrieving statistics
10
10
  * @returns Object containing counts of nouns, verbs, metadata entries, and HNSW index size
11
11
  * @throws Error if the instance is not provided or if statistics retrieval fails
12
12
  */
13
13
  export async function getStatistics(instance, options = {}) {
14
14
  if (!instance) {
15
- throw new Error('BrainyData instance must be provided to getStatistics');
15
+ throw new Error('Brainy instance must be provided to getStatistics');
16
16
  }
17
17
  try {
18
18
  return await instance.getStatistics(options);