Prepares the repo for its new home at soulcraftlabs/open-brainy ahead of the Forgejo transfer: package name, publish registry, release script, and every install/import reference across docs, src, tests, examples, and integrations now point at @soulcraftlabs/brainy on The Source. The npmjs storefront leg and byte-identity pair verification are stripped from the release script — The Source is now the only publish target. README gains an Open Brainy explainer and a registry note for consumers. @soulcraft/brainy 10.4.2 was the last release under the old name.
7.6 KiB
7.6 KiB
Brainy Integrations
Connect Brainy to spreadsheets, BI tools, and external systems with zero configuration.
Quick Start
import { Brainy } from '@soulcraftlabs/brainy'
const brain = new Brainy({ integrations: true })
await brain.init()
// That's it! Your endpoints are ready:
console.log(brain.hub.endpoints)
// { odata: '/odata', sheets: '/sheets', sse: '/events', webhooks: '/webhooks' }
Supported Tools
| Tool | Protocol | How to Connect |
|---|---|---|
| Excel | OData | Data → Get Data → From OData Feed → http://your-server/odata |
| Power BI | OData | Get Data → OData Feed → http://your-server/odata |
| Tableau | OData | Connect → OData → http://your-server/odata |
| Google Sheets | REST | Install Apps Script add-on (see below) |
| Any SSE Client | SSE | new EventSource('http://your-server/events') |
Excel (Power Query)
Connect in 3 clicks:
- Data tab → Get Data → From Other Sources → From OData Feed
- Enter URL:
http://your-server/odata - Click OK → Load
Query Options
Excel Power Query supports OData query parameters:
/odata/Entities?$filter=Type eq 'person'&$top=100
/odata/Entities?$select=Id,Type,Metadata_name
/odata/Entities?$orderby=CreatedAt desc
/odata/Entities?$search=machine learning
Refresh Data
- Manual: Data → Refresh All
- Automatic: Query Properties → Set refresh interval
Power BI
Connect:
- Get Data → OData Feed
- Enter URL:
http://your-server/odata - Select tables:
Entities,Relationships - Click Load
Advanced
Power BI DirectQuery is supported for real-time data.
Tableau
Connect:
- Connect → To a Server → OData
- Enter:
http://your-server/odata - Drag tables to canvas
Google Sheets
Setup (5 minutes):
- Open your Google Sheet
- Extensions → Apps Script
- Delete existing code
- Copy
integrations/google-sheets/Code.gsinto the editor - Create new file
Sidebar.html, paste fromintegrations/google-sheets/Sidebar.html - Project Settings → Script properties → Add:
BRAINY_URL=http://your-server
- Save and refresh spreadsheet
Custom Functions:
=BRAINY_QUERY("type:person", 100) // Query entities
=BRAINY_GET("entity-id") // Get one entity
=BRAINY_SIMILAR("machine learning", 5) // Semantic search
=BRAINY_RELATIONS("entity-id", "from") // Get relationships
Sidebar:
Extensions → Brainy → Open Sidebar
- Search and insert results
- Add new entities
- Sync selected range to Brainy
Real-Time Streaming (SSE)
JavaScript:
const source = new EventSource('http://your-server/events')
source.onmessage = (event) => {
const data = JSON.parse(event.data)
console.log('Change:', data)
}
// Filter by type
const filtered = new EventSource('http://your-server/events?types=noun&operations=create,update')
Query Parameters:
types- Entity types:noun,verb,vfsoperations- Operations:create,update,deletenounTypes- Filter by noun type:person,document, etc.
Webhooks
Push events to external URLs:
const brain = new Brainy({ integrations: true })
await brain.init()
// Register a webhook
await brain.hub.webhooks?.register({
url: 'https://your-app.com/webhook',
events: { entityTypes: ['noun'], operations: ['create', 'update'] },
secret: 'your-hmac-secret' // optional, for signature verification
})
Webhook Payload:
{
"events": [
{
"id": "event-123",
"type": "noun",
"operation": "create",
"entityId": "entity-456",
"timestamp": 1704067200000
}
],
"deliveredAt": 1704067201000
}
Signature Verification:
Webhooks include X-Brainy-Signature header with HMAC-SHA256 signature.
Server Examples
Minimal (in-memory):
import { Brainy } from '@soulcraftlabs/brainy'
const brain = new Brainy({ integrations: true })
await brain.init()
// Add some data
await brain.add({ type: 'Person', metadata: { name: 'Alice' } })
// Get connection instructions
console.log(brain.hub.getInstructions())
Express:
import express from 'express'
import { Brainy } from '@soulcraftlabs/brainy'
const app = express()
const brain = new Brainy({
storage: { type: 'filesystem', options: { basePath: './data' } },
integrations: true
})
await brain.init()
app.use(express.json())
// Route all integrations
app.all(['/odata/*', '/sheets/*', '/events/*'], async (req, res) => {
const response = await brain.hub.handleRequest({
method: req.method,
path: req.path,
query: req.query as Record<string, string>,
headers: req.headers as Record<string, string>,
body: req.body
})
res.status(response.status).set(response.headers)
if (response.body) res.json(response.body)
else res.end()
})
app.listen(3000, () => {
console.log('Brainy server ready!')
console.log('Excel/Power BI: http://localhost:3000/odata')
console.log('Google Sheets: http://localhost:3000/sheets')
console.log('SSE Stream: http://localhost:3000/events')
})
Hono (Cloudflare Workers):
import { Hono } from 'hono'
import { Brainy } from '@soulcraftlabs/brainy'
const app = new Hono()
const brain = new Brainy({
storage: { type: 'memory' },
integrations: true
})
await brain.init()
app.all('/odata/*', async (c) => {
const response = await brain.hub.handleRequest({
method: c.req.method,
path: c.req.path,
query: Object.fromEntries(new URL(c.req.url).searchParams),
headers: Object.fromEntries(c.req.raw.headers),
body: await c.req.json().catch(() => undefined)
})
return c.json(response.body, response.status)
})
export default app
Configuration
Custom Base Path:
const brain = new Brainy({
integrations: { basePath: '/api/v1' }
})
await brain.init()
// Endpoints become:
// /api/v1/odata
// /api/v1/sheets
// /api/v1/events
Select Integrations:
// Only OData and Sheets
const brain = new Brainy({
integrations: { enable: ['odata', 'sheets'] }
})
await brain.init()
Per-Integration Config:
const brain = new Brainy({
integrations: {
config: {
odata: { basePath: '/data' },
sse: { heartbeatInterval: 15000 }
}
}
})
await brain.init()
Troubleshooting
Excel: "Can't connect to OData feed"
- Ensure server is running and accessible
- Check firewall settings
- Try opening URL in browser first
Google Sheets: "Brainy URL not configured"
- Add
BRAINY_URLin Apps Script → Project Settings → Script properties
Power BI: "Invalid OData"
- Ensure
$metadataendpoint returns valid XML - Try:
http://your-server/odata/$metadata
SSE: "Connection dropped"
- Check network/proxy timeout settings
- The integration sends heartbeats every 30 seconds by default
API Reference
OData Endpoints
GET /odata/$metadata - Schema (XML)
GET /odata/Entities - List entities
GET /odata/Entities('id') - Get entity
GET /odata/Relationships - List relationships
POST /odata/Entities - Create entity
Sheets Endpoints
GET /sheets/query?q=...&limit=100 - Query entities
GET /sheets/entity/:id - Get entity
GET /sheets/similar?text=...&k=10 - Semantic search
POST /sheets/add - Add entity
SSE Endpoint
GET /events - All events
GET /events?types=noun - Filter by type
GET /events?operations=create,update - Filter by operation