@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.
- package/README.md +304 -555
- package/dist/brainyData.d.ts +83 -2
- package/dist/brainyData.js +536 -66
- package/dist/brainyData.js.map +1 -1
- package/dist/coreTypes.d.ts +74 -12
- package/dist/distributed/configManager.d.ts +9 -0
- package/dist/distributed/configManager.js +129 -10
- package/dist/distributed/configManager.js.map +1 -1
- package/dist/hnsw/hnswIndex.d.ts +1 -1
- package/dist/hnsw/hnswIndex.js +44 -25
- package/dist/hnsw/hnswIndex.js.map +1 -1
- package/dist/hnsw/optimizedHNSWIndex.d.ts +1 -1
- package/dist/hnsw/optimizedHNSWIndex.js +3 -3
- package/dist/hnsw/optimizedHNSWIndex.js.map +1 -1
- package/dist/storage/adapters/baseStorageAdapter.d.ts +18 -2
- package/dist/storage/adapters/baseStorageAdapter.js +69 -4
- package/dist/storage/adapters/baseStorageAdapter.js.map +1 -1
- package/dist/storage/adapters/fileSystemStorage.d.ts +14 -8
- package/dist/storage/adapters/fileSystemStorage.js +90 -22
- package/dist/storage/adapters/fileSystemStorage.js.map +1 -1
- package/dist/storage/adapters/memoryStorage.d.ts +0 -8
- package/dist/storage/adapters/memoryStorage.js +26 -45
- package/dist/storage/adapters/memoryStorage.js.map +1 -1
- package/dist/storage/adapters/opfsStorage.d.ts +40 -8
- package/dist/storage/adapters/opfsStorage.js +195 -44
- package/dist/storage/adapters/opfsStorage.js.map +1 -1
- package/dist/storage/adapters/optimizedS3Search.js +4 -3
- package/dist/storage/adapters/optimizedS3Search.js.map +1 -1
- package/dist/storage/adapters/s3CompatibleStorage.d.ts +3 -10
- package/dist/storage/adapters/s3CompatibleStorage.js +41 -44
- package/dist/storage/adapters/s3CompatibleStorage.js.map +1 -1
- package/dist/storage/backwardCompatibility.d.ts +84 -0
- package/dist/storage/backwardCompatibility.js +141 -0
- package/dist/storage/backwardCompatibility.js.map +1 -0
- package/dist/storage/baseStorage.d.ts +33 -19
- package/dist/storage/baseStorage.js +116 -195
- package/dist/storage/baseStorage.js.map +1 -1
- package/dist/utils/metadataFilter.d.ts +79 -0
- package/dist/utils/metadataFilter.js +229 -0
- package/dist/utils/metadataFilter.js.map +1 -0
- package/dist/utils/metadataIndex.d.ts +148 -0
- package/dist/utils/metadataIndex.js +639 -0
- package/dist/utils/metadataIndex.js.map +1 -0
- package/dist/utils/metadataIndexCache.d.ts +60 -0
- package/dist/utils/metadataIndexCache.js +119 -0
- package/dist/utils/metadataIndexCache.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,32 +7,60 @@
|
|
|
7
7
|
[](https://www.typescriptlang.org/)
|
|
8
8
|
[](CONTRIBUTING.md)
|
|
9
9
|
|
|
10
|
-
**
|
|
10
|
+
**The world's only true Vector + Graph database - unified semantic search and knowledge graphs**
|
|
11
11
|
|
|
12
12
|
</div>
|
|
13
13
|
|
|
14
|
-
## 🔥 MAJOR
|
|
14
|
+
## 🔥 MAJOR UPDATES: What's New in v0.49, v0.48 & v0.46+
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
### 🎯 **v0.49: Filter Discovery & Performance Improvements**
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
**Discover available filters and scale to millions of items!**
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
```javascript
|
|
21
|
+
// Discover what filters are available - O(1) field lookup
|
|
22
|
+
const categories = await brainy.getFilterValues('category')
|
|
23
|
+
// Returns: ['electronics', 'books', 'clothing', ...]
|
|
24
|
+
|
|
25
|
+
const fields = await brainy.getFilterFields() // O(1) operation
|
|
26
|
+
// Returns: ['category', 'price', 'brand', 'rating', ...]
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
- ✅ **Filter Discovery API**: O(1) field discovery for instant filter UI generation
|
|
30
|
+
- ✅ **Improved Performance**: Removed deprecated methods, now uses pagination everywhere
|
|
31
|
+
- ✅ **Better Scalability**: Hybrid indexing with O(1) field access scales to millions
|
|
32
|
+
- ✅ **Smart Caching**: LRU cache for frequently accessed filters
|
|
33
|
+
- ✅ **Zero Configuration**: Everything auto-optimizes based on usage patterns
|
|
34
|
+
|
|
35
|
+
### 🚀 **v0.48: MongoDB-Style Metadata Filtering**
|
|
21
36
|
|
|
22
|
-
|
|
23
|
-
- 🌐 **Hidden Network Calls**: Even "local" models triggered fetch() calls internally
|
|
24
|
-
- 🐛 **Dependency Hell**: Constant `--legacy-peer-deps` issues with Node.js updates
|
|
25
|
-
- 🔧 **Maintenance Burden**: 47+ dependencies to keep compatible across environments
|
|
26
|
-
- 💾 **Huge Models**: 525MB Universal Sentence Encoder models
|
|
37
|
+
**Powerful querying with familiar syntax - filter DURING search for maximum performance!**
|
|
27
38
|
|
|
28
|
-
|
|
39
|
+
```javascript
|
|
40
|
+
const results = await brainy.search("wireless headphones", 10, {
|
|
41
|
+
metadata: {
|
|
42
|
+
category: { $in: ["electronics", "audio"] },
|
|
43
|
+
price: { $lte: 200 },
|
|
44
|
+
rating: { $gte: 4.0 },
|
|
45
|
+
brand: { $ne: "Generic" }
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
```
|
|
29
49
|
|
|
30
|
-
- ✅ **
|
|
31
|
-
- ✅ **
|
|
32
|
-
- ✅ **
|
|
33
|
-
- ✅ **
|
|
34
|
-
|
|
35
|
-
|
|
50
|
+
- ✅ **15+ MongoDB Operators**: `$gt`, `$in`, `$regex`, `$and`, `$or`, `$includes`, etc.
|
|
51
|
+
- ✅ **Automatic Indexing**: Zero configuration, maximum performance
|
|
52
|
+
- ✅ **Nested Fields**: Use dot notation for complex objects
|
|
53
|
+
- ✅ **100% Backward Compatible**: Your existing code works unchanged
|
|
54
|
+
|
|
55
|
+
### ⚡ **v0.46: Transformers.js Migration**
|
|
56
|
+
|
|
57
|
+
**Replaced TensorFlow.js for better performance and true offline operation!**
|
|
58
|
+
|
|
59
|
+
- ✅ **95% Smaller Package**: 643 kB vs 12.5 MB
|
|
60
|
+
- ✅ **84% Smaller Models**: 87 MB vs 525 MB models
|
|
61
|
+
- ✅ **True Offline**: Zero network calls after initial download
|
|
62
|
+
- ✅ **5x Fewer Dependencies**: Clean tree, no peer dependency issues
|
|
63
|
+
- ✅ **Same API**: Drop-in replacement, existing code works unchanged
|
|
36
64
|
|
|
37
65
|
### Migration (It's Automatic!)
|
|
38
66
|
|
|
@@ -56,11 +84,52 @@ RUN npm run download-models # Download during build for offline production
|
|
|
56
84
|
|
|
57
85
|
---
|
|
58
86
|
|
|
87
|
+
## 🏆 Industry First: True Vector + Graph Database
|
|
88
|
+
|
|
89
|
+
**Brainy is the only database that natively combines vector search and graph relationships in a single, unified system.**
|
|
90
|
+
|
|
91
|
+
Unlike other solutions that bolt vector search onto traditional databases or require multiple systems:
|
|
92
|
+
|
|
93
|
+
✅ **Native Vector + Graph Architecture** - Purpose-built for both semantic search AND knowledge graphs
|
|
94
|
+
✅ **Single API, Dual Power** - Vector similarity search AND graph traversal in one database
|
|
95
|
+
✅ **True Semantic Relationships** - Not just "similar vectors" but meaningful connections like "develops", "owns", "causes"
|
|
96
|
+
✅ **Zero Integration Complexity** - No need to sync between Pinecone + Neo4j or pgvector + graph databases
|
|
97
|
+
|
|
98
|
+
**Why This Matters:**
|
|
99
|
+
```javascript
|
|
100
|
+
// Other solutions: Manage 2+ databases
|
|
101
|
+
const vectors = await pinecone.search(query) // Vector search
|
|
102
|
+
const graph = await neo4j.run("MATCH (a)-[r]->(b)") // Graph traversal
|
|
103
|
+
// How do you keep them in sync? 😢
|
|
104
|
+
|
|
105
|
+
// Brainy: One database, both capabilities
|
|
106
|
+
const results = await brainy.search("AI models", 10, {
|
|
107
|
+
includeVerbs: true, // Include relationships
|
|
108
|
+
verbTypes: ["develops"] // Filter by relationship type
|
|
109
|
+
})
|
|
110
|
+
// Everything stays perfectly synchronized! 🎉
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
This revolutionary architecture enables entirely new classes of AI applications that were previously impossible or prohibitively complex.
|
|
114
|
+
|
|
59
115
|
## ✨ What is Brainy?
|
|
60
116
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
117
|
+
**One API. Every environment. Zero configuration.**
|
|
118
|
+
|
|
119
|
+
Brainy is the **AI-native database** that combines vector search and knowledge graphs in one unified API. Write your
|
|
120
|
+
code once, and it runs everywhere - browsers, Node.js, serverless, edge workers - with automatic optimization for each
|
|
121
|
+
environment.
|
|
122
|
+
|
|
123
|
+
```javascript
|
|
124
|
+
// This same code works EVERYWHERE
|
|
125
|
+
const brainy = new BrainyData()
|
|
126
|
+
await brainy.init()
|
|
127
|
+
|
|
128
|
+
// Vector search (like Pinecone) + Graph database (like Neo4j)
|
|
129
|
+
await brainy.add("OpenAI", { type: "company" }) // Nouns
|
|
130
|
+
await brainy.relate(openai, gpt4, "develops") // Verbs
|
|
131
|
+
const results = await brainy.search("AI", 10) // Semantic search
|
|
132
|
+
```
|
|
64
133
|
|
|
65
134
|
### 🆕 NEW: Distributed Mode (v0.38+)
|
|
66
135
|
|
|
@@ -78,7 +147,8 @@ easy-to-use package.
|
|
|
78
147
|
environment and optimizes itself
|
|
79
148
|
- **🌍 True Write-Once, Run-Anywhere** - Same code runs in Angular, React, Vue, Node.js, Deno, Bun, serverless, edge
|
|
80
149
|
workers, and web workers with automatic environment detection
|
|
81
|
-
- **⚡ Scary Fast** - Handles millions of vectors with sub-millisecond search. GPU acceleration for embeddings, optimized
|
|
150
|
+
- **⚡ Scary Fast** - Handles millions of vectors with sub-millisecond search. GPU acceleration for embeddings, optimized
|
|
151
|
+
CPU for distance calculations
|
|
82
152
|
- **🎯 Self-Learning** - Like having a database that goes to the gym. Gets faster and smarter the more you use it
|
|
83
153
|
- **🔮 AI-First Design** - Built for the age of embeddings, RAG, and semantic search. Your LLMs will thank you
|
|
84
154
|
- **🎮 Actually Fun to Use** - Clean API, great DX, and it does the heavy lifting so you can build cool stuff
|
|
@@ -103,41 +173,51 @@ npm install @soulcraft/brainy
|
|
|
103
173
|
```javascript
|
|
104
174
|
import { BrainyData } from '@soulcraft/brainy'
|
|
105
175
|
|
|
176
|
+
// Same code works EVERYWHERE - browser, Node.js, cloud, edge
|
|
106
177
|
const brainy = new BrainyData()
|
|
107
178
|
await brainy.init() // Auto-detects your environment
|
|
108
179
|
|
|
109
|
-
//
|
|
110
|
-
await brainy.add("The quick brown fox jumps over the lazy dog")
|
|
111
|
-
await brainy.add("
|
|
112
|
-
await brainy.add("Cats are independent and mysterious animals")
|
|
180
|
+
// 1️⃣ Simple vector search (like Pinecone)
|
|
181
|
+
await brainy.add("The quick brown fox jumps over the lazy dog", { type: "sentence" })
|
|
182
|
+
await brainy.add("Cats are independent and mysterious animals", { type: "sentence" })
|
|
113
183
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
console.log(results) // Finds the fox sentences!
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
**🎯 That's it!** You just built semantic search in 4 lines. Works in Angular, React, Vue, Node.js, browsers,
|
|
120
|
-
serverless - everywhere.
|
|
184
|
+
const results = await brainy.search("fast animals", 5)
|
|
185
|
+
// Finds similar content by meaning, not keywords!
|
|
121
186
|
|
|
122
|
-
|
|
187
|
+
// 2️⃣ Graph relationships (like Neo4j)
|
|
188
|
+
const openai = await brainy.add("OpenAI", { type: "company", founded: 2015 })
|
|
189
|
+
const gpt4 = await brainy.add("GPT-4", { type: "product", released: 2023 })
|
|
190
|
+
const sam = await brainy.add("Sam Altman", { type: "person", role: "CEO" })
|
|
123
191
|
|
|
124
|
-
|
|
192
|
+
// Create relationships between entities
|
|
193
|
+
await brainy.relate(openai, gpt4, "develops")
|
|
194
|
+
await brainy.relate(sam, openai, "leads")
|
|
195
|
+
await brainy.relate(gpt4, sam, "created_by")
|
|
125
196
|
|
|
126
|
-
|
|
127
|
-
//
|
|
128
|
-
const
|
|
129
|
-
const
|
|
197
|
+
// 3️⃣ Combined power: Vector search + Graph traversal
|
|
198
|
+
const similar = await brainy.search("AI language models", 10) // Find by meaning
|
|
199
|
+
const products = await brainy.getVerbsBySource(openai) // Get relationships
|
|
200
|
+
const graph = await brainy.findSimilar(gpt4, { relationType: "develops" })
|
|
130
201
|
|
|
131
|
-
//
|
|
132
|
-
await brainy.
|
|
202
|
+
// 4️⃣ Advanced: Search with context
|
|
203
|
+
const contextual = await brainy.search("Who leads AI companies?", 5, {
|
|
204
|
+
includeVerbs: true, // Include relationships in results
|
|
205
|
+
nounTypes: ["person"], // Filter to specific entity types
|
|
206
|
+
})
|
|
133
207
|
|
|
134
|
-
//
|
|
135
|
-
const
|
|
136
|
-
|
|
208
|
+
// 5️⃣ NEW! MongoDB-style metadata filtering
|
|
209
|
+
const filtered = await brainy.search("AI research", 10, {
|
|
210
|
+
metadata: {
|
|
211
|
+
type: "academic",
|
|
212
|
+
year: { $gte: 2020 },
|
|
213
|
+
status: { $in: ["published", "peer-reviewed"] },
|
|
214
|
+
impact: { $gt: 100 }
|
|
215
|
+
}
|
|
216
|
+
})
|
|
217
|
+
// Filters DURING search for maximum performance!
|
|
137
218
|
```
|
|
138
219
|
|
|
139
|
-
|
|
140
|
-
together seamlessly.
|
|
220
|
+
**🎯 That's it!** Vector search + graph database + works everywhere. No config needed.
|
|
141
221
|
|
|
142
222
|
### 🔍 Want More Power?
|
|
143
223
|
|
|
@@ -162,335 +242,148 @@ returns "tiger"
|
|
|
162
242
|
**🌐 Real-Time Collaboration** - Sync vector data across devices. Figma for AI data
|
|
163
243
|
**🏥 Medical Diagnosis Tools** - Match symptoms to conditions using embedding similarity
|
|
164
244
|
|
|
165
|
-
## 🚀
|
|
245
|
+
## 🚀 Works Everywhere - Same Code
|
|
166
246
|
|
|
167
|
-
|
|
168
|
-
developer experience. Choose your environment:
|
|
247
|
+
**Write once, run anywhere.** Brainy auto-detects your environment and optimizes automatically:
|
|
169
248
|
|
|
170
|
-
###
|
|
249
|
+
### 🌐 Browser Frameworks (React, Angular, Vue)
|
|
171
250
|
|
|
172
|
-
```
|
|
173
|
-
|
|
251
|
+
```javascript
|
|
252
|
+
import { BrainyData } from '@soulcraft/brainy'
|
|
253
|
+
|
|
254
|
+
// SAME CODE in React, Angular, Vue, Svelte, etc.
|
|
255
|
+
const brainy = new BrainyData()
|
|
256
|
+
await brainy.init() // Auto-uses OPFS in browsers
|
|
257
|
+
|
|
258
|
+
// Add entities and relationships
|
|
259
|
+
const john = await brainy.add("John is a software engineer", { type: "person" })
|
|
260
|
+
const jane = await brainy.add("Jane is a data scientist", { type: "person" })
|
|
261
|
+
const ai = await brainy.add("AI Project", { type: "project" })
|
|
262
|
+
|
|
263
|
+
await brainy.relate(john, ai, "works_on")
|
|
264
|
+
await brainy.relate(jane, ai, "leads")
|
|
265
|
+
|
|
266
|
+
// Search by meaning
|
|
267
|
+
const engineers = await brainy.search("software developers", 5)
|
|
268
|
+
|
|
269
|
+
// Traverse relationships
|
|
270
|
+
const team = await brainy.getVerbsByTarget(ai) // Who works on AI Project?
|
|
174
271
|
```
|
|
175
272
|
|
|
273
|
+
<details>
|
|
274
|
+
<summary>📦 Full Angular Component Example</summary>
|
|
275
|
+
|
|
176
276
|
```typescript
|
|
177
277
|
import { Component, signal, OnInit } from '@angular/core'
|
|
178
278
|
import { BrainyData } from '@soulcraft/brainy'
|
|
179
279
|
|
|
180
280
|
@Component({
|
|
181
281
|
selector: 'app-search',
|
|
182
|
-
template:
|
|
183
|
-
<div class="search-container">
|
|
184
|
-
<input [(ngModel)]="query"
|
|
185
|
-
(input)="search($event.target.value)"
|
|
186
|
-
placeholder="Search by meaning (try 'pets' or 'food')..."
|
|
187
|
-
class="search-input">
|
|
188
|
-
|
|
189
|
-
<div class="results">
|
|
190
|
-
@for (result of results(); track result.id) {
|
|
191
|
-
<div class="result-item">
|
|
192
|
-
<strong>{{result.metadata?.category}}</strong>: {{result.metadata?.originalData}}
|
|
193
|
-
<small>Similarity: {{result.score | number:'1.2-2'}}</small>
|
|
194
|
-
</div>
|
|
195
|
-
}
|
|
196
|
-
</div>
|
|
197
|
-
</div>
|
|
198
|
-
`
|
|
282
|
+
template: `<input (input)="search($event.target.value)" placeholder="Search...">`
|
|
199
283
|
})
|
|
200
284
|
export class SearchComponent implements OnInit {
|
|
201
|
-
|
|
202
|
-
results = signal<any[]>([])
|
|
203
|
-
query = ''
|
|
285
|
+
brainy = new BrainyData()
|
|
204
286
|
|
|
205
287
|
async ngOnInit() {
|
|
206
|
-
// Auto-detects environment and uses OPFS storage in browsers
|
|
207
|
-
this.brainy = new BrainyData({
|
|
208
|
-
defaultService: 'my-app'
|
|
209
|
-
})
|
|
210
288
|
await this.brainy.init()
|
|
211
|
-
|
|
212
|
-
// Add sample data
|
|
213
|
-
await this.brainy.add("Cats are amazing pets", { category: "animals" })
|
|
214
|
-
await this.brainy.add("Dogs love to play fetch", { category: "animals" })
|
|
215
|
-
await this.brainy.add("Pizza is delicious food", { category: "food" })
|
|
289
|
+
// Add your data...
|
|
216
290
|
}
|
|
217
291
|
|
|
218
292
|
async search(query: string) {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
return
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
const searchResults = await this.brainy.search(query, 5)
|
|
225
|
-
this.results.set(searchResults)
|
|
293
|
+
const results = await this.brainy.search(query, 5)
|
|
294
|
+
// Display results...
|
|
226
295
|
}
|
|
227
296
|
}
|
|
228
297
|
```
|
|
229
298
|
|
|
230
|
-
|
|
299
|
+
</details>
|
|
231
300
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
```
|
|
301
|
+
<details>
|
|
302
|
+
<summary>📦 Full React Example</summary>
|
|
235
303
|
|
|
236
304
|
```jsx
|
|
237
305
|
import { BrainyData } from '@soulcraft/brainy'
|
|
238
306
|
import { useEffect, useState } from 'react'
|
|
239
307
|
|
|
240
|
-
function
|
|
308
|
+
function Search() {
|
|
241
309
|
const [brainy, setBrainy] = useState(null)
|
|
242
310
|
const [results, setResults] = useState([])
|
|
243
|
-
const [query, setQuery] = useState('')
|
|
244
|
-
const [loading, setLoading] = useState(true)
|
|
245
311
|
|
|
246
312
|
useEffect(() => {
|
|
247
|
-
async
|
|
248
|
-
|
|
249
|
-
const db = new BrainyData({
|
|
250
|
-
defaultService: 'my-app'
|
|
251
|
-
})
|
|
313
|
+
const init = async () => {
|
|
314
|
+
const db = new BrainyData()
|
|
252
315
|
await db.init()
|
|
253
|
-
|
|
254
|
-
// Add sample data
|
|
255
|
-
await db.add("Cats are amazing pets", { category: "animals" })
|
|
256
|
-
await db.add("Dogs love to play fetch", { category: "animals" })
|
|
257
|
-
await db.add("Pizza is delicious food", { category: "food" })
|
|
258
|
-
|
|
316
|
+
// Add your data...
|
|
259
317
|
setBrainy(db)
|
|
260
|
-
setLoading(false)
|
|
261
318
|
}
|
|
262
|
-
|
|
263
|
-
initBrainy()
|
|
319
|
+
init()
|
|
264
320
|
}, [])
|
|
265
321
|
|
|
266
|
-
const search = async (
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
const searchResults = await brainy.search(searchQuery, 5)
|
|
270
|
-
setResults(searchResults)
|
|
322
|
+
const search = async (query) => {
|
|
323
|
+
const results = await brainy?.search(query, 5) || []
|
|
324
|
+
setResults(results)
|
|
271
325
|
}
|
|
272
326
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
return (
|
|
276
|
-
<div className="search-container">
|
|
277
|
-
<input
|
|
278
|
-
value={query}
|
|
279
|
-
onChange={(e) => {
|
|
280
|
-
setQuery(e.target.value)
|
|
281
|
-
search(e.target.value)
|
|
282
|
-
}}
|
|
283
|
-
placeholder="Search by meaning (try 'pets' or 'food')..."
|
|
284
|
-
className="search-input"
|
|
285
|
-
/>
|
|
286
|
-
|
|
287
|
-
<div className="results">
|
|
288
|
-
{results.map((result, i) => (
|
|
289
|
-
<div key={result.id} className="result-item">
|
|
290
|
-
<strong>{result.metadata?.category}</strong>: {result.metadata?.originalData}
|
|
291
|
-
<small>Similarity: {result.score.toFixed(2)}</small>
|
|
292
|
-
</div>
|
|
293
|
-
))}
|
|
294
|
-
</div>
|
|
295
|
-
</div>
|
|
296
|
-
)
|
|
327
|
+
return <input onChange={(e) => search(e.target.value)} placeholder="Search..." />
|
|
297
328
|
}
|
|
298
|
-
|
|
299
|
-
export default SemanticSearch
|
|
300
329
|
```
|
|
301
330
|
|
|
302
|
-
|
|
331
|
+
</details>
|
|
303
332
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
```
|
|
333
|
+
<details>
|
|
334
|
+
<summary>📦 Full Vue Example</summary>
|
|
307
335
|
|
|
308
336
|
```vue
|
|
309
337
|
|
|
310
|
-
<template>
|
|
311
|
-
<div class="search-container">
|
|
312
|
-
<input
|
|
313
|
-
v-model="query"
|
|
314
|
-
@input="search"
|
|
315
|
-
placeholder="Search by meaning (try 'pets' or 'food')..."
|
|
316
|
-
class="search-input"
|
|
317
|
-
/>
|
|
318
|
-
|
|
319
|
-
<div v-if="loading" class="loading">
|
|
320
|
-
Initializing Brainy...
|
|
321
|
-
</div>
|
|
322
|
-
|
|
323
|
-
<div v-else class="results">
|
|
324
|
-
<div
|
|
325
|
-
v-for="result in results"
|
|
326
|
-
:key="result.id"
|
|
327
|
-
class="result-item"
|
|
328
|
-
>
|
|
329
|
-
<strong>{{ result.metadata?.category }}</strong>: {{ result.metadata?.originalData }}
|
|
330
|
-
<small>Similarity: {{ result.score.toFixed(2) }}</small>
|
|
331
|
-
</div>
|
|
332
|
-
</div>
|
|
333
|
-
</div>
|
|
334
|
-
</template>
|
|
335
|
-
|
|
336
338
|
<script setup>
|
|
337
339
|
import { BrainyData } from '@soulcraft/brainy'
|
|
338
340
|
import { ref, onMounted } from 'vue'
|
|
339
341
|
|
|
340
342
|
const brainy = ref(null)
|
|
341
343
|
const results = ref([])
|
|
342
|
-
const query = ref('')
|
|
343
|
-
const loading = ref(true)
|
|
344
344
|
|
|
345
345
|
onMounted(async () => {
|
|
346
|
-
|
|
347
|
-
const db = new BrainyData({
|
|
348
|
-
defaultService: 'my-app'
|
|
349
|
-
})
|
|
346
|
+
const db = new BrainyData()
|
|
350
347
|
await db.init()
|
|
351
|
-
|
|
352
|
-
// Add sample data
|
|
353
|
-
await db.add("Cats are amazing pets", { category: "animals" })
|
|
354
|
-
await db.add("Dogs love to play fetch", { category: "animals" })
|
|
355
|
-
await db.add("Pizza is delicious food", { category: "food" })
|
|
356
|
-
|
|
348
|
+
// Add your data...
|
|
357
349
|
brainy.value = db
|
|
358
|
-
loading.value = false
|
|
359
350
|
})
|
|
360
351
|
|
|
361
|
-
const search = async () => {
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
return
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
const searchResults = await brainy.value.search(query.value, 5)
|
|
368
|
-
results.value = searchResults
|
|
352
|
+
const search = async (query) => {
|
|
353
|
+
const results = await brainy.value?.search(query, 5) || []
|
|
354
|
+
setResults(results)
|
|
369
355
|
}
|
|
370
356
|
</script>
|
|
371
357
|
|
|
372
|
-
<
|
|
373
|
-
.
|
|
374
|
-
|
|
375
|
-
margin: 0 auto;
|
|
376
|
-
padding: 20px;
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
.search-input {
|
|
380
|
-
width: 100%;
|
|
381
|
-
padding: 12px;
|
|
382
|
-
margin-bottom: 20px;
|
|
383
|
-
border: 2px solid #ddd;
|
|
384
|
-
border-radius: 8px;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
.result-item {
|
|
388
|
-
padding: 12px;
|
|
389
|
-
border: 1px solid #eee;
|
|
390
|
-
margin-bottom: 8px;
|
|
391
|
-
border-radius: 6px;
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
.loading {
|
|
395
|
-
text-align: center;
|
|
396
|
-
color: #666;
|
|
397
|
-
}
|
|
398
|
-
</style>
|
|
399
|
-
```
|
|
400
|
-
|
|
401
|
-
### 🟢 Node.js Server
|
|
402
|
-
|
|
403
|
-
```bash
|
|
404
|
-
npm install @soulcraft/brainy
|
|
358
|
+
<template>
|
|
359
|
+
<input @input="search($event.target.value)" placeholder="Search..." />
|
|
360
|
+
</template>
|
|
405
361
|
```
|
|
406
362
|
|
|
407
|
-
|
|
408
|
-
import { BrainyData } from '@soulcraft/brainy'
|
|
409
|
-
|
|
410
|
-
// Auto-detects Node.js → FileSystem (local) or S3 (production), Worker threads
|
|
411
|
-
const brainy = new BrainyData({
|
|
412
|
-
defaultService: 'my-app',
|
|
413
|
-
// Optional: Production S3 storage
|
|
414
|
-
storage: {
|
|
415
|
-
s3Storage: {
|
|
416
|
-
bucketName: process.env.S3_BUCKET,
|
|
417
|
-
region: process.env.AWS_REGION,
|
|
418
|
-
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
|
419
|
-
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
})
|
|
423
|
-
await brainy.init()
|
|
424
|
-
|
|
425
|
-
// Same API everywhere
|
|
426
|
-
await brainy.add("Cats are amazing pets", { category: "animals" })
|
|
427
|
-
const results = await brainy.search("pets", 5)
|
|
428
|
-
console.log('Search results:', results)
|
|
429
|
-
```
|
|
363
|
+
</details>
|
|
430
364
|
|
|
431
|
-
###
|
|
365
|
+
### 🟢 Node.js / Serverless / Edge
|
|
432
366
|
|
|
433
367
|
```javascript
|
|
434
368
|
import { BrainyData } from '@soulcraft/brainy'
|
|
435
369
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
defaultService: 'my-app',
|
|
440
|
-
// Optional: Explicit S3-compatible storage
|
|
441
|
-
storage: {
|
|
442
|
-
r2Storage: {
|
|
443
|
-
bucketName: process.env.R2_BUCKET,
|
|
444
|
-
accessKeyId: process.env.R2_ACCESS_KEY_ID,
|
|
445
|
-
secretAccessKey: process.env.R2_SECRET_ACCESS_KEY,
|
|
446
|
-
accountId: process.env.R2_ACCOUNT_ID
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
})
|
|
450
|
-
await brainy.init()
|
|
451
|
-
|
|
452
|
-
// Same API everywhere
|
|
453
|
-
const results = await brainy.search(req.query.q, 5)
|
|
454
|
-
res.json({ results })
|
|
455
|
-
}
|
|
456
|
-
```
|
|
457
|
-
|
|
458
|
-
### 🔥 Cloudflare Workers
|
|
370
|
+
// SAME CODE works in Node.js, Vercel, Netlify, Cloudflare Workers, Deno, Bun
|
|
371
|
+
const brainy = new BrainyData()
|
|
372
|
+
await brainy.init() // Auto-detects environment and optimizes
|
|
459
373
|
|
|
460
|
-
|
|
461
|
-
|
|
374
|
+
// Add entities and relationships
|
|
375
|
+
await brainy.add("Python is great for data science", { type: "fact" })
|
|
376
|
+
await brainy.add("JavaScript rules the web", { type: "fact" })
|
|
462
377
|
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
// Auto-detects edge → Minimal footprint, KV storage
|
|
466
|
-
const brainy = new BrainyData({
|
|
467
|
-
defaultService: 'edge-app'
|
|
468
|
-
})
|
|
469
|
-
await brainy.init()
|
|
378
|
+
// Search by meaning
|
|
379
|
+
const results = await brainy.search("programming languages", 5)
|
|
470
380
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
381
|
+
// Optional: Production with S3/R2 storage (auto-detected in cloud environments)
|
|
382
|
+
const productionBrainy = new BrainyData({
|
|
383
|
+
storage: {
|
|
384
|
+
s3Storage: { bucketName: process.env.BUCKET_NAME }
|
|
475
385
|
}
|
|
476
|
-
}
|
|
477
|
-
```
|
|
478
|
-
|
|
479
|
-
### 🦕 Deno
|
|
480
|
-
|
|
481
|
-
```typescript
|
|
482
|
-
import { BrainyData } from 'https://esm.sh/@soulcraft/brainy'
|
|
483
|
-
|
|
484
|
-
// Auto-detects Deno → Native compatibility, FileSystem storage
|
|
485
|
-
const brainy = new BrainyData({
|
|
486
|
-
defaultService: 'deno-app'
|
|
487
386
|
})
|
|
488
|
-
await brainy.init()
|
|
489
|
-
|
|
490
|
-
// Same API everywhere
|
|
491
|
-
await brainy.add("Deno is awesome", { category: "tech" })
|
|
492
|
-
const results = await brainy.search("technology", 5)
|
|
493
|
-
console.log(results)
|
|
494
387
|
```
|
|
495
388
|
|
|
496
389
|
**That's it! Same code, everywhere. Zero-to-Smart™**
|
|
@@ -510,7 +403,7 @@ Brainy automatically detects and optimizes for:
|
|
|
510
403
|
|
|
511
404
|
```dockerfile
|
|
512
405
|
# One line extracts models automatically during build
|
|
513
|
-
RUN npm run
|
|
406
|
+
RUN npm run download-models
|
|
514
407
|
|
|
515
408
|
# Deploy anywhere: Google Cloud, AWS, Azure, Cloudflare, etc.
|
|
516
409
|
```
|
|
@@ -577,6 +470,7 @@ console.log(`Instance ${health.instanceId}: ${health.status}`)
|
|
|
577
470
|
### Core Capabilities
|
|
578
471
|
|
|
579
472
|
- **Vector Search** - Find semantically similar content using embeddings
|
|
473
|
+
- **MongoDB-Style Metadata Filtering** 🆕 - Advanced filtering with `$gt`, `$in`, `$regex`, `$and`, `$or` operators
|
|
580
474
|
- **Graph Relationships** - Connect data with meaningful relationships
|
|
581
475
|
- **JSON Document Search** - Search within specific fields with prioritization
|
|
582
476
|
- **Distributed Mode** - Scale horizontally with automatic coordination between instances
|
|
@@ -684,6 +578,7 @@ npm install @soulcraft/brainy @soulcraft/brainy-models
|
|
|
684
578
|
- **🎯 Zero Configuration** - Automatic detection with graceful fallback
|
|
685
579
|
- **🔐 Enhanced Security** - Complete air-gapping support for sensitive environments
|
|
686
580
|
- **🏢 Enterprise Ready** - Works behind corporate firewalls and restricted networks
|
|
581
|
+
- **⚖️ Compliance & Forensics** - Frozen mode for audit trails and legal discovery
|
|
687
582
|
|
|
688
583
|
The offline models provide the **same functionality** with maximum reliability. Your existing code works unchanged -
|
|
689
584
|
Brainy automatically detects and uses bundled models when available.
|
|
@@ -712,7 +607,7 @@ const brainy = createAutoBrainy({
|
|
|
712
607
|
2. **Add to your Dockerfile:**
|
|
713
608
|
```dockerfile
|
|
714
609
|
# Extract models during build (zero configuration!)
|
|
715
|
-
RUN npm run
|
|
610
|
+
RUN npm run download-models
|
|
716
611
|
|
|
717
612
|
# Include models in final image
|
|
718
613
|
COPY --from=builder /app/models ./models
|
|
@@ -730,15 +625,15 @@ const brainy = createAutoBrainy({
|
|
|
730
625
|
### Universal Dockerfile Template
|
|
731
626
|
|
|
732
627
|
```dockerfile
|
|
733
|
-
FROM node:24-
|
|
628
|
+
FROM node:24-slim AS builder
|
|
734
629
|
WORKDIR /app
|
|
735
630
|
COPY package*.json ./
|
|
736
631
|
RUN npm ci
|
|
737
632
|
COPY . .
|
|
738
|
-
RUN npm run
|
|
633
|
+
RUN npm run download-models # ← Automatic model download
|
|
739
634
|
RUN npm run build
|
|
740
635
|
|
|
741
|
-
FROM node:24-
|
|
636
|
+
FROM node:24-slim AS production
|
|
742
637
|
WORKDIR /app
|
|
743
638
|
COPY package*.json ./
|
|
744
639
|
RUN npm ci --only=production --omit=optional
|
|
@@ -876,7 +771,8 @@ const writer = createAutoBrainy({
|
|
|
876
771
|
|
|
877
772
|
const reader = createAutoBrainy({
|
|
878
773
|
storage: { s3Storage: { bucketName: 'my-bucket' } },
|
|
879
|
-
readOnly: true, // Automatically becomes 'reader' role
|
|
774
|
+
readOnly: true, // Automatically becomes 'reader' role (allows optimizations)
|
|
775
|
+
// frozen: true, // Optional: Complete immutability for compliance/forensics
|
|
880
776
|
distributed: true
|
|
881
777
|
})
|
|
882
778
|
```
|
|
@@ -938,6 +834,25 @@ const health = brainy.getHealthStatus()
|
|
|
938
834
|
- **Writers**: Optimized write batching, minimal cache
|
|
939
835
|
- **Hybrid**: Adaptive based on workload
|
|
940
836
|
|
|
837
|
+
## ⚖️ Compliance & Forensics Mode
|
|
838
|
+
|
|
839
|
+
For legal discovery, audit trails, and compliance requirements:
|
|
840
|
+
|
|
841
|
+
```javascript
|
|
842
|
+
// Create a completely immutable snapshot
|
|
843
|
+
const auditDb = new BrainyData({
|
|
844
|
+
storage: { s3Storage: { bucketName: 'audit-snapshots' } },
|
|
845
|
+
readOnly: true,
|
|
846
|
+
frozen: true // Complete immutability - no changes allowed
|
|
847
|
+
})
|
|
848
|
+
|
|
849
|
+
// Perfect for:
|
|
850
|
+
// - Legal discovery (data cannot be modified)
|
|
851
|
+
// - Compliance audits (guaranteed state)
|
|
852
|
+
// - Forensic analysis (preserved evidence)
|
|
853
|
+
// - Regulatory snapshots (unchanging records)
|
|
854
|
+
```
|
|
855
|
+
|
|
941
856
|
### Deployment Examples
|
|
942
857
|
|
|
943
858
|
**Docker Compose**
|
|
@@ -998,6 +913,13 @@ spec:
|
|
|
998
913
|
❌ **Neo4j** - Great for graphs, no vector support
|
|
999
914
|
✅ **Brainy** - Vectors + graphs in one. Best of both worlds
|
|
1000
915
|
|
|
916
|
+
### vs. "Vector + Graph" Solutions
|
|
917
|
+
|
|
918
|
+
❌ **Pinecone + Neo4j** - Two databases, sync nightmares, double the cost
|
|
919
|
+
❌ **pgvector + graph extension** - Hacked together, not native, performance issues
|
|
920
|
+
❌ **Weaviate "references"** - Limited graph capabilities, not true relationships
|
|
921
|
+
✅ **Brainy** - Purpose-built vector+graph architecture, single source of truth
|
|
922
|
+
|
|
1001
923
|
### vs. DIY Solutions
|
|
1002
924
|
|
|
1003
925
|
❌ **Building your own** - Months of work, optimization nightmares
|
|
@@ -1005,51 +927,41 @@ spec:
|
|
|
1005
927
|
|
|
1006
928
|
## 🚀 Getting Started in 30 Seconds
|
|
1007
929
|
|
|
1008
|
-
|
|
930
|
+
**The same Brainy code works everywhere - React, Vue, Angular, Node.js, Serverless, Edge Workers.**
|
|
1009
931
|
|
|
1010
|
-
```
|
|
1011
|
-
|
|
1012
|
-
import {
|
|
932
|
+
```javascript
|
|
933
|
+
// This EXACT code works in ALL environments
|
|
934
|
+
import { BrainyData } from '@soulcraft/brainy'
|
|
1013
935
|
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
const [results, setResults] = useState([])
|
|
936
|
+
const brainy = new BrainyData()
|
|
937
|
+
await brainy.init()
|
|
1017
938
|
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
}
|
|
939
|
+
// Add nouns (entities)
|
|
940
|
+
const openai = await brainy.add("OpenAI", { type: "company" })
|
|
941
|
+
const gpt4 = await brainy.add("GPT-4", { type: "product" })
|
|
1022
942
|
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
943
|
+
// Add verbs (relationships)
|
|
944
|
+
await brainy.relate(openai, gpt4, "develops")
|
|
945
|
+
|
|
946
|
+
// Vector search + Graph traversal
|
|
947
|
+
const similar = await brainy.search("AI companies", 5)
|
|
948
|
+
const products = await brainy.getVerbsBySource(openai)
|
|
1028
949
|
```
|
|
1029
950
|
|
|
1030
|
-
|
|
951
|
+
<details>
|
|
952
|
+
<summary>🔍 See Framework Examples</summary>
|
|
1031
953
|
|
|
1032
|
-
|
|
1033
|
-
import { Component, OnInit } from '@angular/core'
|
|
1034
|
-
import { createAutoBrainy } from 'brainy'
|
|
954
|
+
### React
|
|
1035
955
|
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
placeholder="Semantic search...">
|
|
1041
|
-
<div *ngFor="let result of results">
|
|
1042
|
-
{{ result.text }}
|
|
1043
|
-
</div>
|
|
1044
|
-
`
|
|
1045
|
-
})
|
|
1046
|
-
export class SearchComponent implements OnInit {
|
|
1047
|
-
brainy = createAutoBrainy()
|
|
1048
|
-
results = []
|
|
956
|
+
```jsx
|
|
957
|
+
function App() {
|
|
958
|
+
const [brainy] = useState(() => new BrainyData())
|
|
959
|
+
useEffect(() => brainy.init(), [])
|
|
1049
960
|
|
|
1050
|
-
async
|
|
1051
|
-
|
|
961
|
+
const search = async (query) => {
|
|
962
|
+
return await brainy.search(query, 10)
|
|
1052
963
|
}
|
|
964
|
+
// Same API as above
|
|
1053
965
|
}
|
|
1054
966
|
```
|
|
1055
967
|
|
|
@@ -1058,128 +970,66 @@ export class SearchComponent implements OnInit {
|
|
|
1058
970
|
```vue
|
|
1059
971
|
|
|
1060
972
|
<script setup>
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
const brainy = createAutoBrainy()
|
|
1065
|
-
const results = ref([])
|
|
1066
|
-
|
|
1067
|
-
const search = async (query) => {
|
|
1068
|
-
results.value = await brainy.searchText(query, 10)
|
|
1069
|
-
}
|
|
973
|
+
const brainy = new BrainyData()
|
|
974
|
+
await brainy.init()
|
|
975
|
+
// Same API as above
|
|
1070
976
|
</script>
|
|
1071
|
-
|
|
1072
|
-
<template>
|
|
1073
|
-
<input @input="search($event.target.value)"
|
|
1074
|
-
placeholder="Find similar content...">
|
|
1075
|
-
<div v-for="result in results" :key="result.id">
|
|
1076
|
-
{{ result.text }}
|
|
1077
|
-
</div>
|
|
1078
|
-
</template>
|
|
1079
977
|
```
|
|
1080
978
|
|
|
1081
|
-
###
|
|
1082
|
-
|
|
1083
|
-
```svelte
|
|
1084
|
-
<script>
|
|
1085
|
-
import { createAutoBrainy } from 'brainy'
|
|
1086
|
-
|
|
1087
|
-
const brainy = createAutoBrainy()
|
|
1088
|
-
let results = []
|
|
1089
|
-
|
|
1090
|
-
async function search(e) {
|
|
1091
|
-
results = await brainy.searchText(e.target.value, 10)
|
|
1092
|
-
}
|
|
1093
|
-
</script>
|
|
979
|
+
### Angular
|
|
1094
980
|
|
|
1095
|
-
|
|
1096
|
-
{#each results as result}
|
|
1097
|
-
<div>{result.text}</div>
|
|
1098
|
-
{/each}
|
|
1099
|
-
```
|
|
981
|
+
```typescript
|
|
1100
982
|
|
|
1101
|
-
|
|
983
|
+
@Component({})
|
|
984
|
+
export class AppComponent {
|
|
985
|
+
brainy = new BrainyData()
|
|
1102
986
|
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
export default function SearchPage() {
|
|
1108
|
-
async function search(formData) {
|
|
1109
|
-
'use server'
|
|
1110
|
-
const brainy = createAutoBrainy({ bucketName: 'vectors' })
|
|
1111
|
-
const query = formData.get('query')
|
|
1112
|
-
return await brainy.searchText(query, 10)
|
|
987
|
+
async ngOnInit() {
|
|
988
|
+
await this.brainy.init()
|
|
989
|
+
// Same API as above
|
|
1113
990
|
}
|
|
1114
|
-
|
|
1115
|
-
return (
|
|
1116
|
-
<form action={search}>
|
|
1117
|
-
<input name="query" placeholder="Search..." />
|
|
1118
|
-
<button type="submit">Search</button>
|
|
1119
|
-
</form>
|
|
1120
|
-
)
|
|
1121
991
|
}
|
|
1122
992
|
```
|
|
1123
993
|
|
|
1124
|
-
### Node.js /
|
|
994
|
+
### Node.js / Deno / Bun
|
|
1125
995
|
|
|
1126
996
|
```javascript
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
// Add some data
|
|
1132
|
-
await brainy.add("TypeScript is a typed superset of JavaScript", {
|
|
1133
|
-
category: 'programming'
|
|
1134
|
-
})
|
|
1135
|
-
|
|
1136
|
-
// Search for similar content
|
|
1137
|
-
const results = await brainy.searchText("JavaScript with types", 5)
|
|
1138
|
-
console.log(results)
|
|
997
|
+
const brainy = new BrainyData()
|
|
998
|
+
await brainy.init()
|
|
999
|
+
// Same API as above
|
|
1139
1000
|
```
|
|
1140
1001
|
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
**Brainy is designed for modern frameworks** with automatic environment detection and storage selection:
|
|
1144
|
-
|
|
1145
|
-
**✨ Supported environments:**
|
|
1002
|
+
</details>
|
|
1146
1003
|
|
|
1147
|
-
|
|
1148
|
-
- 🟢 **Node.js/Deno/Bun** - Full server-side capabilities
|
|
1149
|
-
- ⚡ **Serverless/Edge** - Optimized for cold starts and minimal footprint
|
|
1150
|
-
- 🧵 **Web/Worker threads** - Thread-safe, shared storage
|
|
1151
|
-
|
|
1152
|
-
**🗄️ Auto-selected storage:**
|
|
1004
|
+
### 🌍 Framework-First, Runs Everywhere
|
|
1153
1005
|
|
|
1154
|
-
|
|
1155
|
-
- 📁 **FileSystem** - Node.js servers (local development)
|
|
1156
|
-
- ☁️ **S3/R2/GCS** - Production, serverless, distributed deployments
|
|
1157
|
-
- 💾 **Memory** - Edge workers, testing, temporary data
|
|
1006
|
+
**Brainy automatically detects your environment and optimizes everything:**
|
|
1158
1007
|
|
|
1159
|
-
|
|
1008
|
+
| Environment | Storage | Optimization |
|
|
1009
|
+
|-----------------|-----------------|----------------------------|
|
|
1010
|
+
| 🌐 Browser | OPFS | Web Workers, Memory Cache |
|
|
1011
|
+
| 🟢 Node.js | FileSystem / S3 | Worker Threads, Clustering |
|
|
1012
|
+
| ⚡ Serverless | S3 / Memory | Cold Start Optimization |
|
|
1013
|
+
| 🔥 Edge Workers | Memory / KV | Minimal Footprint |
|
|
1014
|
+
| 🦕 Deno/Bun | FileSystem / S3 | Native Performance |
|
|
1160
1015
|
|
|
1161
|
-
|
|
1162
|
-
- ✅ **Type safety** - Full TypeScript integration and IntelliSense
|
|
1163
|
-
- ✅ **State management** - Reactive updates and component lifecycle
|
|
1164
|
-
- ✅ **Production ready** - Tree-shaking, optimization, error boundaries
|
|
1016
|
+
## 🌐 Deploy to Any Cloud
|
|
1165
1017
|
|
|
1166
|
-
|
|
1018
|
+
<details>
|
|
1019
|
+
<summary>☁️ See Cloud Platform Examples</summary>
|
|
1167
1020
|
|
|
1168
1021
|
### Cloudflare Workers
|
|
1169
1022
|
|
|
1170
1023
|
```javascript
|
|
1171
|
-
import {
|
|
1024
|
+
import { BrainyData } from '@soulcraft/brainy'
|
|
1172
1025
|
|
|
1173
1026
|
export default {
|
|
1174
|
-
async fetch(request
|
|
1175
|
-
const brainy =
|
|
1176
|
-
|
|
1177
|
-
})
|
|
1027
|
+
async fetch(request) {
|
|
1028
|
+
const brainy = new BrainyData()
|
|
1029
|
+
await brainy.init()
|
|
1178
1030
|
|
|
1179
1031
|
const url = new URL(request.url)
|
|
1180
|
-
const
|
|
1181
|
-
|
|
1182
|
-
const results = await brainy.searchText(query, 10)
|
|
1032
|
+
const results = await brainy.search(url.searchParams.get('q'), 10)
|
|
1183
1033
|
return Response.json(results)
|
|
1184
1034
|
}
|
|
1185
1035
|
}
|
|
@@ -1188,156 +1038,54 @@ export default {
|
|
|
1188
1038
|
### AWS Lambda
|
|
1189
1039
|
|
|
1190
1040
|
```javascript
|
|
1191
|
-
import {
|
|
1041
|
+
import { BrainyData } from '@soulcraft/brainy'
|
|
1192
1042
|
|
|
1193
1043
|
export const handler = async (event) => {
|
|
1194
|
-
const brainy =
|
|
1195
|
-
|
|
1196
|
-
})
|
|
1197
|
-
|
|
1198
|
-
const results = await brainy.searchText(event.query, 10)
|
|
1199
|
-
|
|
1200
|
-
return {
|
|
1201
|
-
statusCode: 200,
|
|
1202
|
-
body: JSON.stringify(results)
|
|
1203
|
-
}
|
|
1204
|
-
}
|
|
1205
|
-
```
|
|
1206
|
-
|
|
1207
|
-
### Azure Functions
|
|
1208
|
-
|
|
1209
|
-
```javascript
|
|
1210
|
-
import { createAutoBrainy } from 'brainy'
|
|
1211
|
-
|
|
1212
|
-
module.exports = async function(context, req) {
|
|
1213
|
-
const brainy = createAutoBrainy({
|
|
1214
|
-
bucketName: process.env.AZURE_STORAGE_CONTAINER
|
|
1215
|
-
})
|
|
1216
|
-
|
|
1217
|
-
const results = await brainy.searchText(req.query.q, 10)
|
|
1044
|
+
const brainy = new BrainyData()
|
|
1045
|
+
await brainy.init()
|
|
1218
1046
|
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
}
|
|
1047
|
+
const results = await brainy.search(event.query, 10)
|
|
1048
|
+
return { statusCode: 200, body: JSON.stringify(results) }
|
|
1222
1049
|
}
|
|
1223
1050
|
```
|
|
1224
1051
|
|
|
1225
1052
|
### Google Cloud Functions
|
|
1226
1053
|
|
|
1227
1054
|
```javascript
|
|
1228
|
-
import {
|
|
1055
|
+
import { BrainyData } from '@soulcraft/brainy'
|
|
1229
1056
|
|
|
1230
1057
|
export const searchHandler = async (req, res) => {
|
|
1231
|
-
const brainy =
|
|
1232
|
-
|
|
1233
|
-
})
|
|
1058
|
+
const brainy = new BrainyData()
|
|
1059
|
+
await brainy.init()
|
|
1234
1060
|
|
|
1235
|
-
const results = await brainy.
|
|
1061
|
+
const results = await brainy.search(req.query.q, 10)
|
|
1236
1062
|
res.json(results)
|
|
1237
1063
|
}
|
|
1238
1064
|
```
|
|
1239
1065
|
|
|
1240
|
-
### Google Cloud Run
|
|
1241
|
-
|
|
1242
|
-
```dockerfile
|
|
1243
|
-
# Dockerfile
|
|
1244
|
-
FROM node:20-alpine
|
|
1245
|
-
USER node
|
|
1246
|
-
WORKDIR /app
|
|
1247
|
-
COPY package*.json ./
|
|
1248
|
-
RUN npm install brainy
|
|
1249
|
-
COPY . .
|
|
1250
|
-
CMD ["node", "server.js"]
|
|
1251
|
-
```
|
|
1252
|
-
|
|
1253
|
-
```javascript
|
|
1254
|
-
// server.js
|
|
1255
|
-
import { createAutoBrainy } from 'brainy'
|
|
1256
|
-
import express from 'express'
|
|
1257
|
-
|
|
1258
|
-
const app = express()
|
|
1259
|
-
const brainy = createAutoBrainy({
|
|
1260
|
-
bucketName: process.env.GCS_BUCKET
|
|
1261
|
-
})
|
|
1262
|
-
|
|
1263
|
-
app.get('/search', async (req, res) => {
|
|
1264
|
-
const results = await brainy.searchText(req.query.q, 10)
|
|
1265
|
-
res.json(results)
|
|
1266
|
-
})
|
|
1267
|
-
|
|
1268
|
-
const port = process.env.PORT || 8080
|
|
1269
|
-
app.listen(port, () => console.log(`Brainy on Cloud Run: ${port}`))
|
|
1270
|
-
```
|
|
1271
|
-
|
|
1272
|
-
```bash
|
|
1273
|
-
# Deploy to Cloud Run
|
|
1274
|
-
gcloud run deploy brainy-api \
|
|
1275
|
-
--source . \
|
|
1276
|
-
--platform managed \
|
|
1277
|
-
--region us-central1 \
|
|
1278
|
-
--allow-unauthenticated
|
|
1279
|
-
```
|
|
1280
|
-
|
|
1281
1066
|
### Vercel Edge Functions
|
|
1282
1067
|
|
|
1283
1068
|
```javascript
|
|
1284
|
-
import {
|
|
1069
|
+
import { BrainyData } from '@soulcraft/brainy'
|
|
1285
1070
|
|
|
1286
|
-
export const config = {
|
|
1287
|
-
runtime: 'edge'
|
|
1288
|
-
}
|
|
1071
|
+
export const config = { runtime: 'edge' }
|
|
1289
1072
|
|
|
1290
1073
|
export default async function handler(request) {
|
|
1291
|
-
const brainy =
|
|
1292
|
-
|
|
1293
|
-
const query = searchParams.get('q')
|
|
1074
|
+
const brainy = new BrainyData()
|
|
1075
|
+
await brainy.init()
|
|
1294
1076
|
|
|
1295
|
-
const
|
|
1077
|
+
const { searchParams } = new URL(request.url)
|
|
1078
|
+
const results = await brainy.search(searchParams.get('q'), 10)
|
|
1296
1079
|
return Response.json(results)
|
|
1297
1080
|
}
|
|
1298
1081
|
```
|
|
1299
1082
|
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
```javascript
|
|
1303
|
-
import { createAutoBrainy } from 'brainy'
|
|
1304
|
-
|
|
1305
|
-
export async function handler(event, context) {
|
|
1306
|
-
const brainy = createAutoBrainy()
|
|
1307
|
-
const query = event.queryStringParameters.q
|
|
1308
|
-
|
|
1309
|
-
const results = await brainy.searchText(query, 10)
|
|
1310
|
-
|
|
1311
|
-
return {
|
|
1312
|
-
statusCode: 200,
|
|
1313
|
-
body: JSON.stringify(results)
|
|
1314
|
-
}
|
|
1315
|
-
}
|
|
1316
|
-
```
|
|
1317
|
-
|
|
1318
|
-
### Supabase Edge Functions
|
|
1319
|
-
|
|
1320
|
-
```typescript
|
|
1321
|
-
import { createAutoBrainy } from 'brainy'
|
|
1322
|
-
import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
|
|
1323
|
-
|
|
1324
|
-
serve(async (req) => {
|
|
1325
|
-
const brainy = createAutoBrainy()
|
|
1326
|
-
const url = new URL(req.url)
|
|
1327
|
-
const query = url.searchParams.get('q')
|
|
1328
|
-
|
|
1329
|
-
const results = await brainy.searchText(query, 10)
|
|
1330
|
-
|
|
1331
|
-
return new Response(JSON.stringify(results), {
|
|
1332
|
-
headers: { 'Content-Type': 'application/json' }
|
|
1333
|
-
})
|
|
1334
|
-
})
|
|
1335
|
-
```
|
|
1083
|
+
</details>
|
|
1336
1084
|
|
|
1337
1085
|
### Docker Container
|
|
1338
1086
|
|
|
1339
1087
|
```dockerfile
|
|
1340
|
-
FROM node:
|
|
1088
|
+
FROM node:24-slim
|
|
1341
1089
|
USER node
|
|
1342
1090
|
WORKDIR /app
|
|
1343
1091
|
COPY package*.json ./
|
|
@@ -1420,6 +1168,7 @@ services:
|
|
|
1420
1168
|
|
|
1421
1169
|
- [**Search and Metadata**](docs/user-guides/) - Advanced search techniques
|
|
1422
1170
|
- [**JSON Document Search**](docs/guides/json-document-search.md) - Field-based searching
|
|
1171
|
+
- [**Read-Only & Frozen Modes**](docs/guides/readonly-frozen-modes.md) - Immutability options for production
|
|
1423
1172
|
- [**Production Migration**](docs/guides/production-migration-guide.md) - Deployment best practices
|
|
1424
1173
|
|
|
1425
1174
|
### API Reference
|