@soulcraft/brainy 0.52.0 → 0.54.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.
- package/README.md +154 -0
- package/dist/brainyData.d.ts +38 -0
- package/dist/brainyData.js +104 -3
- package/dist/brainyData.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/storage/adapters/s3CompatibleStorage.d.ts +2 -0
- package/dist/storage/adapters/s3CompatibleStorage.js +46 -65
- package/dist/storage/adapters/s3CompatibleStorage.js.map +1 -1
- package/dist/utils/adaptiveBackpressure.d.ts +103 -0
- package/dist/utils/adaptiveBackpressure.js +342 -0
- package/dist/utils/adaptiveBackpressure.js.map +1 -0
- package/dist/utils/adaptiveSocketManager.d.ts +117 -0
- package/dist/utils/adaptiveSocketManager.js +378 -0
- package/dist/utils/adaptiveSocketManager.js.map +1 -0
- package/dist/utils/performanceMonitor.d.ts +114 -0
- package/dist/utils/performanceMonitor.js +384 -0
- package/dist/utils/performanceMonitor.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -69,6 +69,160 @@ const results = await brainy.search("AI language models", 5, {
|
|
|
69
69
|
|
|
70
70
|
**That's it. You just built a knowledge graph with semantic search and faceted filtering in 8 lines.**
|
|
71
71
|
|
|
72
|
+
## ⚙️ Configuration Options
|
|
73
|
+
|
|
74
|
+
Brainy works great with **zero configuration**, but you can customize it for your specific needs:
|
|
75
|
+
|
|
76
|
+
### 🚀 Quick Start (Recommended)
|
|
77
|
+
```javascript
|
|
78
|
+
const brainy = new BrainyData() // Auto-detects everything
|
|
79
|
+
await brainy.init() // Zero config needed
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### 🎯 Specialized Configurations
|
|
83
|
+
|
|
84
|
+
#### Writer Service with Deduplication
|
|
85
|
+
Perfect for high-throughput data ingestion with smart caching:
|
|
86
|
+
```javascript
|
|
87
|
+
const brainy = new BrainyData({
|
|
88
|
+
writeOnly: true, // Skip search index loading
|
|
89
|
+
allowDirectReads: true // Enable ID-based lookups for deduplication
|
|
90
|
+
})
|
|
91
|
+
// ✅ Can: add(), get(), has(), exists(), getMetadata(), getBatch()
|
|
92
|
+
// ❌ Cannot: search(), similar(), query() (saves memory & startup time)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
#### Pure Writer Service
|
|
96
|
+
For maximum performance data ingestion only:
|
|
97
|
+
```javascript
|
|
98
|
+
const brainy = new BrainyData({
|
|
99
|
+
writeOnly: true, // No search capabilities
|
|
100
|
+
allowDirectReads: false // No read operations at all
|
|
101
|
+
})
|
|
102
|
+
// ✅ Can: add(), addBatch(), relate()
|
|
103
|
+
// ❌ Cannot: Any read operations (fastest startup)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
#### Read-Only Service
|
|
107
|
+
For search-only applications with immutable data:
|
|
108
|
+
```javascript
|
|
109
|
+
const brainy = new BrainyData({
|
|
110
|
+
readOnly: true, // Block all write operations
|
|
111
|
+
frozen: true // Block statistics updates and optimizations
|
|
112
|
+
})
|
|
113
|
+
// ✅ Can: All search operations
|
|
114
|
+
// ❌ Cannot: add(), update(), delete()
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
#### Custom Storage & Performance
|
|
118
|
+
```javascript
|
|
119
|
+
const brainy = new BrainyData({
|
|
120
|
+
// Storage options
|
|
121
|
+
storage: {
|
|
122
|
+
type: 's3', // 's3', 'memory', 'filesystem'
|
|
123
|
+
requestPersistentStorage: true, // Browser: request persistent storage
|
|
124
|
+
s3Storage: {
|
|
125
|
+
bucketName: 'my-vectors',
|
|
126
|
+
region: 'us-east-1'
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
|
|
130
|
+
// Performance tuning
|
|
131
|
+
hnsw: {
|
|
132
|
+
maxConnections: 16, // Higher = better search quality
|
|
133
|
+
efConstruction: 200, // Higher = better index quality
|
|
134
|
+
useOptimized: true // Enable disk-based storage
|
|
135
|
+
},
|
|
136
|
+
|
|
137
|
+
// Embedding customization
|
|
138
|
+
embeddingFunction: myCustomEmbedder,
|
|
139
|
+
distanceFunction: 'euclidean' // 'cosine', 'euclidean', 'manhattan'
|
|
140
|
+
})
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
#### Distributed Services
|
|
144
|
+
```javascript
|
|
145
|
+
// Microservice A (Writer)
|
|
146
|
+
const writerService = new BrainyData({
|
|
147
|
+
writeOnly: true,
|
|
148
|
+
allowDirectReads: true, // For deduplication
|
|
149
|
+
defaultService: 'data-ingestion'
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
// Microservice B (Reader)
|
|
153
|
+
const readerService = new BrainyData({
|
|
154
|
+
readOnly: true,
|
|
155
|
+
defaultService: 'search-api'
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
// Full-featured service
|
|
159
|
+
const hybridService = new BrainyData({
|
|
160
|
+
writeOnly: false, // Can read and write
|
|
161
|
+
defaultService: 'full-stack-app'
|
|
162
|
+
})
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### 🔧 All Configuration Options
|
|
166
|
+
|
|
167
|
+
<details>
|
|
168
|
+
<summary>Click to see complete configuration reference</summary>
|
|
169
|
+
|
|
170
|
+
```javascript
|
|
171
|
+
const brainy = new BrainyData({
|
|
172
|
+
// === Operation Modes ===
|
|
173
|
+
writeOnly?: boolean // Disable search operations, enable fast ingestion
|
|
174
|
+
allowDirectReads?: boolean // Enable ID lookups in writeOnly mode
|
|
175
|
+
readOnly?: boolean // Disable write operations
|
|
176
|
+
frozen?: boolean // Disable all optimizations and statistics
|
|
177
|
+
lazyLoadInReadOnlyMode?: boolean // Load index on-demand
|
|
178
|
+
|
|
179
|
+
// === Storage Configuration ===
|
|
180
|
+
storage?: {
|
|
181
|
+
type?: 'auto' | 'memory' | 'filesystem' | 's3' | 'opfs'
|
|
182
|
+
requestPersistentStorage?: boolean // Browser persistent storage
|
|
183
|
+
|
|
184
|
+
// Cloud storage options
|
|
185
|
+
s3Storage?: {
|
|
186
|
+
bucketName: string
|
|
187
|
+
region?: string
|
|
188
|
+
accessKeyId?: string
|
|
189
|
+
secretAccessKey?: string
|
|
190
|
+
},
|
|
191
|
+
|
|
192
|
+
r2Storage?: { /* Cloudflare R2 options */ },
|
|
193
|
+
gcsStorage?: { /* Google Cloud Storage options */ }
|
|
194
|
+
},
|
|
195
|
+
|
|
196
|
+
// === Performance Tuning ===
|
|
197
|
+
hnsw?: {
|
|
198
|
+
maxConnections?: number // Default: 16
|
|
199
|
+
efConstruction?: number // Default: 200
|
|
200
|
+
efSearch?: number // Default: 50
|
|
201
|
+
useOptimized?: boolean // Default: true
|
|
202
|
+
useDiskBasedIndex?: boolean // Default: auto-detected
|
|
203
|
+
},
|
|
204
|
+
|
|
205
|
+
// === Embedding & Distance ===
|
|
206
|
+
embeddingFunction?: EmbeddingFunction
|
|
207
|
+
distanceFunction?: 'cosine' | 'euclidean' | 'manhattan'
|
|
208
|
+
|
|
209
|
+
// === Service Identity ===
|
|
210
|
+
defaultService?: string // Default service name for operations
|
|
211
|
+
|
|
212
|
+
// === Advanced Options ===
|
|
213
|
+
logging?: {
|
|
214
|
+
verbose?: boolean // Enable detailed logging
|
|
215
|
+
},
|
|
216
|
+
|
|
217
|
+
timeouts?: {
|
|
218
|
+
embedding?: number // Embedding timeout (ms)
|
|
219
|
+
search?: number // Search timeout (ms)
|
|
220
|
+
}
|
|
221
|
+
})
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
</details>
|
|
225
|
+
|
|
72
226
|
## 🔥 MAJOR UPDATES: What's New in v0.51, v0.49 & v0.48
|
|
73
227
|
|
|
74
228
|
### 🎯 **v0.51: Revolutionary Developer Experience**
|
package/dist/brainyData.d.ts
CHANGED
|
@@ -105,6 +105,13 @@ export interface BrainyDataConfig {
|
|
|
105
105
|
* This is useful for data ingestion scenarios where only write operations are needed
|
|
106
106
|
*/
|
|
107
107
|
writeOnly?: boolean;
|
|
108
|
+
/**
|
|
109
|
+
* Allow direct storage reads in write-only mode
|
|
110
|
+
* When true and writeOnly is also true, enables direct ID-based lookups (get, has, exists, getMetadata, getBatch, getVerb)
|
|
111
|
+
* that don't require search indexes. Search operations (search, similar, query, findRelated) remain disabled.
|
|
112
|
+
* This is useful for writer services that need deduplication without loading expensive search indexes.
|
|
113
|
+
*/
|
|
114
|
+
allowDirectReads?: boolean;
|
|
108
115
|
/**
|
|
109
116
|
* Remote server configuration for search operations
|
|
110
117
|
*/
|
|
@@ -354,6 +361,7 @@ export declare class BrainyData<T = any> implements BrainyDataInterface<T> {
|
|
|
354
361
|
private frozen;
|
|
355
362
|
private lazyLoadInReadOnlyMode;
|
|
356
363
|
private writeOnly;
|
|
364
|
+
private allowDirectReads;
|
|
357
365
|
private storageConfig;
|
|
358
366
|
private config;
|
|
359
367
|
private useOptimizedIndex;
|
|
@@ -410,6 +418,7 @@ export declare class BrainyData<T = any> implements BrainyDataInterface<T> {
|
|
|
410
418
|
/**
|
|
411
419
|
* Check if the database is in write-only mode and throw an error if it is
|
|
412
420
|
* @param allowExistenceChecks If true, allows existence checks (get operations) in write-only mode
|
|
421
|
+
* @param isDirectStorageOperation If true, allows the operation when allowDirectReads is enabled
|
|
413
422
|
* @throws Error if the database is in write-only mode and operation is not allowed
|
|
414
423
|
*/
|
|
415
424
|
private checkWriteOnly;
|
|
@@ -699,6 +708,34 @@ export declare class BrainyData<T = any> implements BrainyDataInterface<T> {
|
|
|
699
708
|
* Get a vector by ID
|
|
700
709
|
*/
|
|
701
710
|
get(id: string): Promise<VectorDocument<T> | null>;
|
|
711
|
+
/**
|
|
712
|
+
* Check if a document with the given ID exists
|
|
713
|
+
* This is a direct storage operation that works in write-only mode when allowDirectReads is enabled
|
|
714
|
+
* @param id The ID to check for existence
|
|
715
|
+
* @returns Promise<boolean> True if the document exists, false otherwise
|
|
716
|
+
*/
|
|
717
|
+
has(id: string): Promise<boolean>;
|
|
718
|
+
/**
|
|
719
|
+
* Check if a document with the given ID exists (alias for has)
|
|
720
|
+
* This is a direct storage operation that works in write-only mode when allowDirectReads is enabled
|
|
721
|
+
* @param id The ID to check for existence
|
|
722
|
+
* @returns Promise<boolean> True if the document exists, false otherwise
|
|
723
|
+
*/
|
|
724
|
+
exists(id: string): Promise<boolean>;
|
|
725
|
+
/**
|
|
726
|
+
* Get metadata for a document by ID
|
|
727
|
+
* This is a direct storage operation that works in write-only mode when allowDirectReads is enabled
|
|
728
|
+
* @param id The ID of the document
|
|
729
|
+
* @returns Promise<T | null> The metadata object or null if not found
|
|
730
|
+
*/
|
|
731
|
+
getMetadata(id: string): Promise<T | null>;
|
|
732
|
+
/**
|
|
733
|
+
* Get multiple documents by their IDs
|
|
734
|
+
* This is a direct storage operation that works in write-only mode when allowDirectReads is enabled
|
|
735
|
+
* @param ids Array of IDs to retrieve
|
|
736
|
+
* @returns Promise<Array<VectorDocument<T> | null>> Array of documents (null for missing IDs)
|
|
737
|
+
*/
|
|
738
|
+
getBatch(ids: string[]): Promise<Array<VectorDocument<T> | null>>;
|
|
702
739
|
/**
|
|
703
740
|
* Get all nouns in the database
|
|
704
741
|
* @returns Array of vector documents
|
|
@@ -789,6 +826,7 @@ export declare class BrainyData<T = any> implements BrainyDataInterface<T> {
|
|
|
789
826
|
}): Promise<string>;
|
|
790
827
|
/**
|
|
791
828
|
* Get a verb by ID
|
|
829
|
+
* This is a direct storage operation that works in write-only mode when allowDirectReads is enabled
|
|
792
830
|
*/
|
|
793
831
|
getVerb(id: string): Promise<GraphVerb | null>;
|
|
794
832
|
/**
|
package/dist/brainyData.js
CHANGED
|
@@ -122,6 +122,8 @@ export class BrainyData {
|
|
|
122
122
|
this.lazyLoadInReadOnlyMode = config.lazyLoadInReadOnlyMode || false;
|
|
123
123
|
// Set write-only flag
|
|
124
124
|
this.writeOnly = config.writeOnly || false;
|
|
125
|
+
// Set allowDirectReads flag
|
|
126
|
+
this.allowDirectReads = config.allowDirectReads || false;
|
|
125
127
|
// Validate that readOnly and writeOnly are not both true
|
|
126
128
|
if (this.readOnly && this.writeOnly) {
|
|
127
129
|
throw new Error('Database cannot be both read-only and write-only');
|
|
@@ -227,11 +229,15 @@ export class BrainyData {
|
|
|
227
229
|
/**
|
|
228
230
|
* Check if the database is in write-only mode and throw an error if it is
|
|
229
231
|
* @param allowExistenceChecks If true, allows existence checks (get operations) in write-only mode
|
|
232
|
+
* @param isDirectStorageOperation If true, allows the operation when allowDirectReads is enabled
|
|
230
233
|
* @throws Error if the database is in write-only mode and operation is not allowed
|
|
231
234
|
*/
|
|
232
|
-
checkWriteOnly(allowExistenceChecks = false) {
|
|
233
|
-
if (this.writeOnly && !allowExistenceChecks) {
|
|
234
|
-
throw new Error('Cannot perform search operation: database is in write-only mode.
|
|
235
|
+
checkWriteOnly(allowExistenceChecks = false, isDirectStorageOperation = false) {
|
|
236
|
+
if (this.writeOnly && !allowExistenceChecks && !(isDirectStorageOperation && this.allowDirectReads)) {
|
|
237
|
+
throw new Error('Cannot perform search operation: database is in write-only mode. ' +
|
|
238
|
+
(this.allowDirectReads
|
|
239
|
+
? 'Direct storage operations (get, has, exists, getMetadata, getBatch, getVerb) are allowed.'
|
|
240
|
+
: 'Use get() for existence checks or enable allowDirectReads for direct storage operations.'));
|
|
235
241
|
}
|
|
236
242
|
}
|
|
237
243
|
/**
|
|
@@ -2026,6 +2032,96 @@ export class BrainyData {
|
|
|
2026
2032
|
throw new Error(`Failed to get vector ${id}: ${error}`);
|
|
2027
2033
|
}
|
|
2028
2034
|
}
|
|
2035
|
+
/**
|
|
2036
|
+
* Check if a document with the given ID exists
|
|
2037
|
+
* This is a direct storage operation that works in write-only mode when allowDirectReads is enabled
|
|
2038
|
+
* @param id The ID to check for existence
|
|
2039
|
+
* @returns Promise<boolean> True if the document exists, false otherwise
|
|
2040
|
+
*/
|
|
2041
|
+
async has(id) {
|
|
2042
|
+
if (id === null || id === undefined) {
|
|
2043
|
+
throw new Error('ID cannot be null or undefined');
|
|
2044
|
+
}
|
|
2045
|
+
await this.ensureInitialized();
|
|
2046
|
+
// This is a direct storage operation - check if allowed in write-only mode
|
|
2047
|
+
if (this.writeOnly && !this.allowDirectReads) {
|
|
2048
|
+
throw new Error('Cannot perform has() operation: database is in write-only mode. Enable allowDirectReads for direct storage operations.');
|
|
2049
|
+
}
|
|
2050
|
+
try {
|
|
2051
|
+
// Always query storage directly for existence check
|
|
2052
|
+
const noun = await this.storage.getNoun(id);
|
|
2053
|
+
return noun !== null;
|
|
2054
|
+
}
|
|
2055
|
+
catch (error) {
|
|
2056
|
+
// If storage lookup fails, the item doesn't exist
|
|
2057
|
+
return false;
|
|
2058
|
+
}
|
|
2059
|
+
}
|
|
2060
|
+
/**
|
|
2061
|
+
* Check if a document with the given ID exists (alias for has)
|
|
2062
|
+
* This is a direct storage operation that works in write-only mode when allowDirectReads is enabled
|
|
2063
|
+
* @param id The ID to check for existence
|
|
2064
|
+
* @returns Promise<boolean> True if the document exists, false otherwise
|
|
2065
|
+
*/
|
|
2066
|
+
async exists(id) {
|
|
2067
|
+
return this.has(id);
|
|
2068
|
+
}
|
|
2069
|
+
/**
|
|
2070
|
+
* Get metadata for a document by ID
|
|
2071
|
+
* This is a direct storage operation that works in write-only mode when allowDirectReads is enabled
|
|
2072
|
+
* @param id The ID of the document
|
|
2073
|
+
* @returns Promise<T | null> The metadata object or null if not found
|
|
2074
|
+
*/
|
|
2075
|
+
async getMetadata(id) {
|
|
2076
|
+
if (id === null || id === undefined) {
|
|
2077
|
+
throw new Error('ID cannot be null or undefined');
|
|
2078
|
+
}
|
|
2079
|
+
await this.ensureInitialized();
|
|
2080
|
+
// This is a direct storage operation - check if allowed in write-only mode
|
|
2081
|
+
if (this.writeOnly && !this.allowDirectReads) {
|
|
2082
|
+
throw new Error('Cannot perform getMetadata() operation: database is in write-only mode. Enable allowDirectReads for direct storage operations.');
|
|
2083
|
+
}
|
|
2084
|
+
try {
|
|
2085
|
+
const metadata = await this.storage.getMetadata(id);
|
|
2086
|
+
return metadata;
|
|
2087
|
+
}
|
|
2088
|
+
catch (error) {
|
|
2089
|
+
console.error(`Failed to get metadata for ${id}:`, error);
|
|
2090
|
+
return null;
|
|
2091
|
+
}
|
|
2092
|
+
}
|
|
2093
|
+
/**
|
|
2094
|
+
* Get multiple documents by their IDs
|
|
2095
|
+
* This is a direct storage operation that works in write-only mode when allowDirectReads is enabled
|
|
2096
|
+
* @param ids Array of IDs to retrieve
|
|
2097
|
+
* @returns Promise<Array<VectorDocument<T> | null>> Array of documents (null for missing IDs)
|
|
2098
|
+
*/
|
|
2099
|
+
async getBatch(ids) {
|
|
2100
|
+
if (!Array.isArray(ids)) {
|
|
2101
|
+
throw new Error('IDs must be provided as an array');
|
|
2102
|
+
}
|
|
2103
|
+
await this.ensureInitialized();
|
|
2104
|
+
// This is a direct storage operation - check if allowed in write-only mode
|
|
2105
|
+
if (this.writeOnly && !this.allowDirectReads) {
|
|
2106
|
+
throw new Error('Cannot perform getBatch() operation: database is in write-only mode. Enable allowDirectReads for direct storage operations.');
|
|
2107
|
+
}
|
|
2108
|
+
const results = [];
|
|
2109
|
+
for (const id of ids) {
|
|
2110
|
+
if (id === null || id === undefined) {
|
|
2111
|
+
results.push(null);
|
|
2112
|
+
continue;
|
|
2113
|
+
}
|
|
2114
|
+
try {
|
|
2115
|
+
const result = await this.get(id);
|
|
2116
|
+
results.push(result);
|
|
2117
|
+
}
|
|
2118
|
+
catch (error) {
|
|
2119
|
+
console.error(`Failed to get document ${id} in batch:`, error);
|
|
2120
|
+
results.push(null);
|
|
2121
|
+
}
|
|
2122
|
+
}
|
|
2123
|
+
return results;
|
|
2124
|
+
}
|
|
2029
2125
|
/**
|
|
2030
2126
|
* Get all nouns in the database
|
|
2031
2127
|
* @returns Array of vector documents
|
|
@@ -2690,9 +2786,14 @@ export class BrainyData {
|
|
|
2690
2786
|
}
|
|
2691
2787
|
/**
|
|
2692
2788
|
* Get a verb by ID
|
|
2789
|
+
* This is a direct storage operation that works in write-only mode when allowDirectReads is enabled
|
|
2693
2790
|
*/
|
|
2694
2791
|
async getVerb(id) {
|
|
2695
2792
|
await this.ensureInitialized();
|
|
2793
|
+
// This is a direct storage operation - check if allowed in write-only mode
|
|
2794
|
+
if (this.writeOnly && !this.allowDirectReads) {
|
|
2795
|
+
throw new Error('Cannot perform getVerb() operation: database is in write-only mode. Enable allowDirectReads for direct storage operations.');
|
|
2796
|
+
}
|
|
2696
2797
|
try {
|
|
2697
2798
|
// Get the lightweight verb from storage
|
|
2698
2799
|
const hnswVerb = await this.storage.getVerb(id);
|