diff --git a/cli-package/package-lock.json b/cli-package/package-lock.json index 3126c3af..7f4cc2b5 100644 --- a/cli-package/package-lock.json +++ b/cli-package/package-lock.json @@ -1,16 +1,16 @@ { "name": "@soulcraft/brainy-cli", - "version": "0.18.0", + "version": "0.19.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@soulcraft/brainy-cli", - "version": "0.18.0", + "version": "0.19.0", "hasInstallScript": true, "license": "MIT", "dependencies": { - "@soulcraft/brainy": "^0.17.0", + "@soulcraft/brainy": "^0.24.0", "commander": "^14.0.0", "omelette": "^0.4.17" }, @@ -2087,9 +2087,9 @@ } }, "node_modules/@soulcraft/brainy": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@soulcraft/brainy/-/brainy-0.17.0.tgz", - "integrity": "sha512-QoTiNnyK7fBuNRDsGOcP89UrFfwxoqkS6lRh6VpIXAWVTtxUBy256PWxQAqtZgpslOZRAA58GlXIQf3IYHiM5g==", + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@soulcraft/brainy/-/brainy-0.24.0.tgz", + "integrity": "sha512-9ZkzNQpqVx4N17i7KPU2pDufrmiXPO/pAonftpwWuHL8sIGI8xJhWzxUIG063jBNOzmMItF2/UEggJS1SpozgA==", "license": "MIT", "dependencies": { "@aws-sdk/client-s3": "^3.540.0", diff --git a/cli-package/package.json b/cli-package/package.json index 049f8597..3cc20b41 100644 --- a/cli-package/package.json +++ b/cli-package/package.json @@ -1,6 +1,6 @@ { "name": "@soulcraft/brainy-cli", - "version": "0.18.0", + "version": "0.19.0", "description": "Command-line interface for the Brainy vector graph database", "type": "module", "bin": { @@ -46,7 +46,7 @@ "url": "git+https://github.com/soulcraft-research/brainy.git" }, "dependencies": { - "@soulcraft/brainy": "^0.17.0", + "@soulcraft/brainy": "^0.24.0", "commander": "^14.0.0", "omelette": "^0.4.17" }, diff --git a/web-service-package/dist/server.js b/web-service-package/dist/server.js index 3895253e..5d1622ed 100644 --- a/web-service-package/dist/server.js +++ b/web-service-package/dist/server.js @@ -118,7 +118,6 @@ async function initializeBrainy() { // Initialize the storage adapter before using it await storage.init(); brainyInstance = new BrainyData({ - dimensions: 384, // Default dimensions, can be overridden storageAdapter: storage, distanceFunction: cosineDistance }); @@ -128,7 +127,6 @@ async function initializeBrainy() { if (!brainyInstance) { const storage = await createStorage(storageOptions); brainyInstance = new BrainyData({ - dimensions: 384, // Default dimensions, can be overridden storageAdapter: storage, distanceFunction: cosineDistance }); diff --git a/web-service-package/dist/server.js.map b/web-service-package/dist/server.js.map index 5716523f..8b1861a9 100644 --- a/web-service-package/dist/server.js.map +++ b/web-service-package/dist/server.js.map @@ -1 +1 @@ -{"version":3,"file":"server.js","sources":["../src/server.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport express from 'express'\nimport cors from 'cors'\nimport helmet from 'helmet'\nimport compression from 'compression'\nimport rateLimit from 'express-rate-limit'\nimport { body, query, param, validationResult } from 'express-validator'\nimport { BrainyData, createStorage, cosineDistance } from '@soulcraft/brainy'\nimport { fileURLToPath } from 'url'\nimport { dirname, join } from 'path'\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = dirname(__filename)\n\n// Configuration\nconst PORT = process.env.PORT || 3000\nconst HOST = process.env.HOST || '0.0.0.0'\nconst DATA_PATH = process.env.BRAINY_DATA_PATH || join(__dirname, '..', 'data')\nconst CORS_ORIGIN = process.env.CORS_ORIGIN || '*'\nconst RATE_LIMIT_WINDOW = parseInt(process.env.RATE_LIMIT_WINDOW || '900000') // 15 minutes\nconst RATE_LIMIT_MAX = parseInt(process.env.RATE_LIMIT_MAX || '100') // 100 requests per window\n\n// Cloud Storage Configuration\n// The createStorage function will automatically detect and use these environment variables:\n// AWS S3: S3_BUCKET_NAME, S3_ACCESS_KEY_ID (or AWS_ACCESS_KEY_ID), S3_SECRET_ACCESS_KEY (or AWS_SECRET_ACCESS_KEY), S3_REGION (or AWS_REGION)\n// Cloudflare R2: R2_BUCKET_NAME, R2_ACCOUNT_ID, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY\n// Google Cloud Storage: GCS_BUCKET_NAME, GCS_ACCESS_KEY_ID, GCS_SECRET_ACCESS_KEY, GCS_ENDPOINT\n// Force local storage: FORCE_LOCAL_STORAGE=true\n\n// Initialize Express app\nconst app = express()\n\n// Security middleware\napp.use(helmet({\n contentSecurityPolicy: {\n directives: {\n defaultSrc: [\"'self'\"],\n styleSrc: [\"'self'\", \"'unsafe-inline'\"],\n scriptSrc: [\"'self'\"],\n imgSrc: [\"'self'\", \"data:\", \"https:\"],\n },\n },\n}))\n\napp.use(cors({\n origin: CORS_ORIGIN,\n methods: ['GET', 'POST'],\n allowedHeaders: ['Content-Type', 'Authorization'],\n}))\n\napp.use(compression())\napp.use(express.json({ limit: '10mb' }))\n\n// Rate limiting\nconst limiter = rateLimit({\n windowMs: RATE_LIMIT_WINDOW,\n max: RATE_LIMIT_MAX,\n message: {\n error: 'Too many requests from this IP, please try again later.',\n retryAfter: Math.ceil(RATE_LIMIT_WINDOW / 1000)\n },\n standardHeaders: true,\n legacyHeaders: false,\n})\n\napp.use('/api/', limiter)\n\n// Global BrainyData instance\nlet brainyInstance: BrainyData | null = null\n\n// Initialize BrainyData instance\nasync function initializeBrainy(): Promise {\n if (brainyInstance) {\n return brainyInstance\n }\n\n try {\n console.log('Initializing Brainy database...')\n \n // Create storage adapter with cloud support\n const storageOptions: any = {\n requestPersistentStorage: true\n }\n \n // Add AWS S3 configuration if environment variables are present\n if (process.env.S3_BUCKET_NAME) {\n storageOptions.s3Storage = {\n bucketName: process.env.S3_BUCKET_NAME,\n region: process.env.S3_REGION || process.env.AWS_REGION || 'us-east-1',\n accessKeyId: process.env.S3_ACCESS_KEY_ID || process.env.AWS_ACCESS_KEY_ID,\n secretAccessKey: process.env.S3_SECRET_ACCESS_KEY || process.env.AWS_SECRET_ACCESS_KEY,\n sessionToken: process.env.S3_SESSION_TOKEN || process.env.AWS_SESSION_TOKEN\n }\n }\n \n // Add Cloudflare R2 configuration if environment variables are present\n if (process.env.R2_BUCKET_NAME) {\n storageOptions.r2Storage = {\n bucketName: process.env.R2_BUCKET_NAME,\n accountId: process.env.R2_ACCOUNT_ID,\n accessKeyId: process.env.R2_ACCESS_KEY_ID,\n secretAccessKey: process.env.R2_SECRET_ACCESS_KEY\n }\n }\n \n // Add Google Cloud Storage configuration if environment variables are present\n if (process.env.GCS_BUCKET_NAME) {\n storageOptions.gcsStorage = {\n bucketName: process.env.GCS_BUCKET_NAME,\n region: process.env.GCS_REGION,\n endpoint: process.env.GCS_ENDPOINT,\n accessKeyId: process.env.GCS_ACCESS_KEY_ID,\n secretAccessKey: process.env.GCS_SECRET_ACCESS_KEY\n }\n }\n \n // Check if local storage is forced\n if (process.env.FORCE_LOCAL_STORAGE === 'true') {\n console.log('Forcing local filesystem storage (FORCE_LOCAL_STORAGE=true)')\n storageOptions.forceFileSystemStorage = true\n // Set the data path for local storage\n if (DATA_PATH) {\n // We'll need to import FileSystemStorage and path for forced local storage\n const { FileSystemStorage } = await import('@soulcraft/brainy')\n const path = await import('path')\n \n // Create storage with explicit path handling to avoid race condition\n const nounsDir = path.join(DATA_PATH, 'nouns')\n const verbsDir = path.join(DATA_PATH, 'verbs')\n const metadataDir = path.join(DATA_PATH, 'metadata')\n const indexDir = path.join(DATA_PATH, 'index')\n \n // Create a storage instance with pre-computed paths\n const storage = new FileSystemStorage(DATA_PATH)\n \n // Initialize the storage adapter before using it\n await storage.init()\n \n brainyInstance = new BrainyData({\n dimensions: 384, // Default dimensions, can be overridden\n storageAdapter: storage,\n distanceFunction: cosineDistance\n })\n }\n }\n \n // If not forcing local storage or no specific data path, use createStorage\n if (!brainyInstance) {\n const storage = await createStorage(storageOptions)\n \n brainyInstance = new BrainyData({\n dimensions: 384, // Default dimensions, can be overridden\n storageAdapter: storage,\n distanceFunction: cosineDistance\n })\n }\n\n await brainyInstance.init()\n \n // Force read-only mode for security\n brainyInstance.setReadOnly(true)\n \n // Log storage information\n console.log(`Brainy database initialized in read-only mode`)\n console.log(`Database size: ${brainyInstance.size()} items`)\n \n return brainyInstance\n } catch (error) {\n console.error('Failed to initialize Brainy database:', error)\n throw error\n }\n}\n\n// Error handler middleware\nconst handleValidationErrors = (req: express.Request, res: express.Response, next: express.NextFunction) => {\n const errors = validationResult(req)\n if (!errors.isEmpty()) {\n return res.status(400).json({\n error: 'Validation failed',\n details: errors.array()\n })\n }\n next()\n}\n\n// Health check endpoint\napp.get('/health', (req, res) => {\n res.json({\n status: 'healthy',\n timestamp: new Date().toISOString(),\n service: 'brainy-web-service',\n version: '0.12.0'\n })\n})\n\n// API Documentation endpoint\napp.get('/api', (req, res) => {\n res.json({\n service: 'Brainy Web Service',\n version: '0.12.0',\n description: 'Read-only search service for Brainy vector graph database',\n endpoints: {\n 'GET /health': 'Health check',\n 'GET /api': 'API documentation',\n 'GET /api/status': 'Database status',\n 'POST /api/search': 'Search for similar vectors',\n 'POST /api/search/text': 'Search using text query',\n 'GET /api/item/:id': 'Get item by ID',\n 'GET /api/items': 'Get all items (paginated)',\n 'POST /api/similar/:id': 'Find similar items to given ID'\n },\n security: {\n readOnly: true,\n rateLimit: {\n windowMs: RATE_LIMIT_WINDOW,\n maxRequests: RATE_LIMIT_MAX\n }\n }\n })\n})\n\n// Database status endpoint\napp.get('/api/status', async (req, res) => {\n try {\n const brainy = await initializeBrainy()\n const status = await brainy.status()\n \n res.json({\n ...status,\n readOnly: brainy.isReadOnly(),\n timestamp: new Date().toISOString()\n })\n } catch (error) {\n console.error('Status check failed:', error)\n res.status(500).json({\n error: 'Failed to get database status',\n message: (error as Error).message\n })\n }\n})\n\n// Search endpoint - vector search\napp.post('/api/search', [\n body('vector').isArray().withMessage('Vector must be an array'),\n body('vector.*').isNumeric().withMessage('Vector elements must be numbers'),\n body('k').optional().isInt({ min: 1, max: 100 }).withMessage('k must be between 1 and 100'),\n body('nounTypes').optional().isArray().withMessage('nounTypes must be an array'),\n body('includeVerbs').optional().isBoolean().withMessage('includeVerbs must be boolean'),\n handleValidationErrors\n], async (req: express.Request, res: express.Response) => {\n try {\n const brainy = await initializeBrainy()\n const { vector, k = 10, nounTypes, includeVerbs = false } = req.body\n \n const results = await brainy.search(vector, k, {\n nounTypes,\n includeVerbs,\n searchMode: 'local' // Force local search for security\n })\n \n res.json({\n results,\n query: {\n vectorLength: vector.length,\n k,\n nounTypes,\n includeVerbs\n },\n timestamp: new Date().toISOString()\n })\n } catch (error) {\n console.error('Search failed:', error)\n res.status(500).json({\n error: 'Search failed',\n message: (error as Error).message\n })\n }\n})\n\n// Text search endpoint\napp.post('/api/search/text', [\n body('query').isString().isLength({ min: 1, max: 1000 }).withMessage('Query must be a string between 1 and 1000 characters'),\n body('k').optional().isInt({ min: 1, max: 100 }).withMessage('k must be between 1 and 100'),\n body('nounTypes').optional().isArray().withMessage('nounTypes must be an array'),\n body('includeVerbs').optional().isBoolean().withMessage('includeVerbs must be boolean'),\n handleValidationErrors\n], async (req: express.Request, res: express.Response) => {\n try {\n const brainy = await initializeBrainy()\n const { query, k = 10, nounTypes, includeVerbs = false } = req.body\n \n const results = await brainy.searchText(query, k, {\n nounTypes,\n includeVerbs\n })\n \n res.json({\n results,\n query: {\n text: query,\n k,\n nounTypes,\n includeVerbs\n },\n timestamp: new Date().toISOString()\n })\n } catch (error) {\n console.error('Text search failed:', error)\n res.status(500).json({\n error: 'Text search failed',\n message: (error as Error).message\n })\n }\n})\n\n// Get item by ID\napp.get('/api/item/:id', [\n param('id').isString().isLength({ min: 1, max: 100 }).withMessage('ID must be a string between 1 and 100 characters'),\n handleValidationErrors\n], async (req: express.Request, res: express.Response) => {\n try {\n const brainy = await initializeBrainy()\n const { id } = req.params\n \n const item = await brainy.get(id)\n \n if (!item) {\n return res.status(404).json({\n error: 'Item not found',\n id\n })\n }\n \n res.json({\n item,\n timestamp: new Date().toISOString()\n })\n } catch (error) {\n console.error('Get item failed:', error)\n res.status(500).json({\n error: 'Failed to get item',\n message: (error as Error).message\n })\n }\n})\n\n// Get all items (paginated)\napp.get('/api/items', [\n query('page').optional().isInt({ min: 1 }).withMessage('Page must be a positive integer'),\n query('limit').optional().isInt({ min: 1, max: 100 }).withMessage('Limit must be between 1 and 100'),\n handleValidationErrors\n], async (req: express.Request, res: express.Response) => {\n try {\n const brainy = await initializeBrainy()\n const page = parseInt(req.query.page as string) || 1\n const limit = parseInt(req.query.limit as string) || 20\n \n const allNouns = await brainy.getAllNouns()\n const total = allNouns.length\n const startIndex = (page - 1) * limit\n const endIndex = startIndex + limit\n const items = allNouns.slice(startIndex, endIndex)\n \n res.json({\n items,\n pagination: {\n page,\n limit,\n total,\n totalPages: Math.ceil(total / limit),\n hasNext: endIndex < total,\n hasPrev: page > 1\n },\n timestamp: new Date().toISOString()\n })\n } catch (error) {\n console.error('Get items failed:', error)\n res.status(500).json({\n error: 'Failed to get items',\n message: (error as Error).message\n })\n }\n})\n\n// Find similar items\napp.post('/api/similar/:id', [\n param('id').isString().isLength({ min: 1, max: 100 }).withMessage('ID must be a string between 1 and 100 characters'),\n body('k').optional().isInt({ min: 1, max: 100 }).withMessage('k must be between 1 and 100'),\n body('includeVerbs').optional().isBoolean().withMessage('includeVerbs must be boolean'),\n handleValidationErrors\n], async (req: express.Request, res: express.Response) => {\n try {\n const brainy = await initializeBrainy()\n const { id } = req.params\n const { k = 10, includeVerbs = false } = req.body\n \n const results = await brainy.findSimilar(id, {\n limit: k,\n includeVerbs\n })\n \n res.json({\n results,\n query: {\n id,\n k,\n includeVerbs\n },\n timestamp: new Date().toISOString()\n })\n } catch (error) {\n console.error('Find similar failed:', error)\n res.status(500).json({\n error: 'Failed to find similar items',\n message: (error as Error).message\n })\n }\n})\n\n// 404 handler\napp.use('*', (req, res) => {\n res.status(404).json({\n error: 'Endpoint not found',\n path: req.originalUrl,\n method: req.method\n })\n})\n\n// Global error handler\napp.use((err: Error, req: express.Request, res: express.Response, next: express.NextFunction) => {\n console.error('Unhandled error:', err)\n res.status(500).json({\n error: 'Internal server error',\n message: process.env.NODE_ENV === 'development' ? err.message : 'Something went wrong'\n })\n})\n\n// Graceful shutdown\nprocess.on('SIGTERM', async () => {\n console.log('SIGTERM received, shutting down gracefully...')\n if (brainyInstance) {\n await brainyInstance.shutDown()\n }\n process.exit(0)\n})\n\nprocess.on('SIGINT', async () => {\n console.log('SIGINT received, shutting down gracefully...')\n if (brainyInstance) {\n await brainyInstance.shutDown()\n }\n process.exit(0)\n})\n\n// Start server\nasync function startServer() {\n try {\n // Initialize Brainy on startup\n await initializeBrainy()\n \n app.listen(Number(PORT), HOST, () => {\n console.log(`🚀 Brainy Web Service started`)\n console.log(`📍 Server running on http://${HOST}:${PORT}`)\n console.log(`📊 API documentation available at http://${HOST}:${PORT}/api`)\n console.log(`🔒 Read-only mode: ${brainyInstance?.isReadOnly()}`)\n console.log(`📁 Data path: ${DATA_PATH}`)\n })\n } catch (error) {\n console.error('Failed to start server:', error)\n process.exit(1)\n }\n}\n\n// Start the server\nstartServer().catch(console.error)\n"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"server.js","sources":["../src/server.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport express from 'express'\nimport cors from 'cors'\nimport helmet from 'helmet'\nimport compression from 'compression'\nimport rateLimit from 'express-rate-limit'\nimport { body, query, param, validationResult } from 'express-validator'\nimport { BrainyData, createStorage, cosineDistance } from '@soulcraft/brainy'\nimport { fileURLToPath } from 'url'\nimport { dirname, join } from 'path'\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = dirname(__filename)\n\n// Configuration\nconst PORT = process.env.PORT || 3000\nconst HOST = process.env.HOST || '0.0.0.0'\nconst DATA_PATH = process.env.BRAINY_DATA_PATH || join(__dirname, '..', 'data')\nconst CORS_ORIGIN = process.env.CORS_ORIGIN || '*'\nconst RATE_LIMIT_WINDOW = parseInt(process.env.RATE_LIMIT_WINDOW || '900000') // 15 minutes\nconst RATE_LIMIT_MAX = parseInt(process.env.RATE_LIMIT_MAX || '100') // 100 requests per window\n\n// Cloud Storage Configuration\n// The createStorage function will automatically detect and use these environment variables:\n// AWS S3: S3_BUCKET_NAME, S3_ACCESS_KEY_ID (or AWS_ACCESS_KEY_ID), S3_SECRET_ACCESS_KEY (or AWS_SECRET_ACCESS_KEY), S3_REGION (or AWS_REGION)\n// Cloudflare R2: R2_BUCKET_NAME, R2_ACCOUNT_ID, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY\n// Google Cloud Storage: GCS_BUCKET_NAME, GCS_ACCESS_KEY_ID, GCS_SECRET_ACCESS_KEY, GCS_ENDPOINT\n// Force local storage: FORCE_LOCAL_STORAGE=true\n\n// Initialize Express app\nconst app = express()\n\n// Security middleware\napp.use(helmet({\n contentSecurityPolicy: {\n directives: {\n defaultSrc: [\"'self'\"],\n styleSrc: [\"'self'\", \"'unsafe-inline'\"],\n scriptSrc: [\"'self'\"],\n imgSrc: [\"'self'\", \"data:\", \"https:\"],\n },\n },\n}))\n\napp.use(cors({\n origin: CORS_ORIGIN,\n methods: ['GET', 'POST'],\n allowedHeaders: ['Content-Type', 'Authorization'],\n}))\n\napp.use(compression())\napp.use(express.json({ limit: '10mb' }))\n\n// Rate limiting\nconst limiter = rateLimit({\n windowMs: RATE_LIMIT_WINDOW,\n max: RATE_LIMIT_MAX,\n message: {\n error: 'Too many requests from this IP, please try again later.',\n retryAfter: Math.ceil(RATE_LIMIT_WINDOW / 1000)\n },\n standardHeaders: true,\n legacyHeaders: false,\n})\n\napp.use('/api/', limiter)\n\n// Global BrainyData instance\nlet brainyInstance: BrainyData | null = null\n\n// Initialize BrainyData instance\nasync function initializeBrainy(): Promise {\n if (brainyInstance) {\n return brainyInstance\n }\n\n try {\n console.log('Initializing Brainy database...')\n \n // Create storage adapter with cloud support\n const storageOptions: any = {\n requestPersistentStorage: true\n }\n \n // Add AWS S3 configuration if environment variables are present\n if (process.env.S3_BUCKET_NAME) {\n storageOptions.s3Storage = {\n bucketName: process.env.S3_BUCKET_NAME,\n region: process.env.S3_REGION || process.env.AWS_REGION || 'us-east-1',\n accessKeyId: process.env.S3_ACCESS_KEY_ID || process.env.AWS_ACCESS_KEY_ID,\n secretAccessKey: process.env.S3_SECRET_ACCESS_KEY || process.env.AWS_SECRET_ACCESS_KEY,\n sessionToken: process.env.S3_SESSION_TOKEN || process.env.AWS_SESSION_TOKEN\n }\n }\n \n // Add Cloudflare R2 configuration if environment variables are present\n if (process.env.R2_BUCKET_NAME) {\n storageOptions.r2Storage = {\n bucketName: process.env.R2_BUCKET_NAME,\n accountId: process.env.R2_ACCOUNT_ID,\n accessKeyId: process.env.R2_ACCESS_KEY_ID,\n secretAccessKey: process.env.R2_SECRET_ACCESS_KEY\n }\n }\n \n // Add Google Cloud Storage configuration if environment variables are present\n if (process.env.GCS_BUCKET_NAME) {\n storageOptions.gcsStorage = {\n bucketName: process.env.GCS_BUCKET_NAME,\n region: process.env.GCS_REGION,\n endpoint: process.env.GCS_ENDPOINT,\n accessKeyId: process.env.GCS_ACCESS_KEY_ID,\n secretAccessKey: process.env.GCS_SECRET_ACCESS_KEY\n }\n }\n \n // Check if local storage is forced\n if (process.env.FORCE_LOCAL_STORAGE === 'true') {\n console.log('Forcing local filesystem storage (FORCE_LOCAL_STORAGE=true)')\n storageOptions.forceFileSystemStorage = true\n // Set the data path for local storage\n if (DATA_PATH) {\n // We'll need to import FileSystemStorage and path for forced local storage\n const { FileSystemStorage } = await import('@soulcraft/brainy')\n const path = await import('path')\n \n // Create storage with explicit path handling to avoid race condition\n const nounsDir = path.join(DATA_PATH, 'nouns')\n const verbsDir = path.join(DATA_PATH, 'verbs')\n const metadataDir = path.join(DATA_PATH, 'metadata')\n const indexDir = path.join(DATA_PATH, 'index')\n \n // Create a storage instance with pre-computed paths\n const storage = new FileSystemStorage(DATA_PATH)\n \n // Initialize the storage adapter before using it\n await storage.init()\n \n brainyInstance = new BrainyData({\n storageAdapter: storage,\n distanceFunction: cosineDistance\n })\n }\n }\n \n // If not forcing local storage or no specific data path, use createStorage\n if (!brainyInstance) {\n const storage = await createStorage(storageOptions)\n \n brainyInstance = new BrainyData({\n storageAdapter: storage,\n distanceFunction: cosineDistance\n })\n }\n\n await brainyInstance.init()\n \n // Force read-only mode for security\n brainyInstance.setReadOnly(true)\n \n // Log storage information\n console.log(`Brainy database initialized in read-only mode`)\n console.log(`Database size: ${brainyInstance.size()} items`)\n \n return brainyInstance\n } catch (error) {\n console.error('Failed to initialize Brainy database:', error)\n throw error\n }\n}\n\n// Error handler middleware\nconst handleValidationErrors = (req: express.Request, res: express.Response, next: express.NextFunction) => {\n const errors = validationResult(req)\n if (!errors.isEmpty()) {\n return res.status(400).json({\n error: 'Validation failed',\n details: errors.array()\n })\n }\n next()\n}\n\n// Health check endpoint\napp.get('/health', (req, res) => {\n res.json({\n status: 'healthy',\n timestamp: new Date().toISOString(),\n service: 'brainy-web-service',\n version: '0.12.0'\n })\n})\n\n// API Documentation endpoint\napp.get('/api', (req, res) => {\n res.json({\n service: 'Brainy Web Service',\n version: '0.12.0',\n description: 'Read-only search service for Brainy vector graph database',\n endpoints: {\n 'GET /health': 'Health check',\n 'GET /api': 'API documentation',\n 'GET /api/status': 'Database status',\n 'POST /api/search': 'Search for similar vectors',\n 'POST /api/search/text': 'Search using text query',\n 'GET /api/item/:id': 'Get item by ID',\n 'GET /api/items': 'Get all items (paginated)',\n 'POST /api/similar/:id': 'Find similar items to given ID'\n },\n security: {\n readOnly: true,\n rateLimit: {\n windowMs: RATE_LIMIT_WINDOW,\n maxRequests: RATE_LIMIT_MAX\n }\n }\n })\n})\n\n// Database status endpoint\napp.get('/api/status', async (req, res) => {\n try {\n const brainy = await initializeBrainy()\n const status = await brainy.status()\n \n res.json({\n ...status,\n readOnly: brainy.isReadOnly(),\n timestamp: new Date().toISOString()\n })\n } catch (error) {\n console.error('Status check failed:', error)\n res.status(500).json({\n error: 'Failed to get database status',\n message: (error as Error).message\n })\n }\n})\n\n// Search endpoint - vector search\napp.post('/api/search', [\n body('vector').isArray().withMessage('Vector must be an array'),\n body('vector.*').isNumeric().withMessage('Vector elements must be numbers'),\n body('k').optional().isInt({ min: 1, max: 100 }).withMessage('k must be between 1 and 100'),\n body('nounTypes').optional().isArray().withMessage('nounTypes must be an array'),\n body('includeVerbs').optional().isBoolean().withMessage('includeVerbs must be boolean'),\n handleValidationErrors\n], async (req: express.Request, res: express.Response) => {\n try {\n const brainy = await initializeBrainy()\n const { vector, k = 10, nounTypes, includeVerbs = false } = req.body\n \n const results = await brainy.search(vector, k, {\n nounTypes,\n includeVerbs,\n searchMode: 'local' // Force local search for security\n })\n \n res.json({\n results,\n query: {\n vectorLength: vector.length,\n k,\n nounTypes,\n includeVerbs\n },\n timestamp: new Date().toISOString()\n })\n } catch (error) {\n console.error('Search failed:', error)\n res.status(500).json({\n error: 'Search failed',\n message: (error as Error).message\n })\n }\n})\n\n// Text search endpoint\napp.post('/api/search/text', [\n body('query').isString().isLength({ min: 1, max: 1000 }).withMessage('Query must be a string between 1 and 1000 characters'),\n body('k').optional().isInt({ min: 1, max: 100 }).withMessage('k must be between 1 and 100'),\n body('nounTypes').optional().isArray().withMessage('nounTypes must be an array'),\n body('includeVerbs').optional().isBoolean().withMessage('includeVerbs must be boolean'),\n handleValidationErrors\n], async (req: express.Request, res: express.Response) => {\n try {\n const brainy = await initializeBrainy()\n const { query, k = 10, nounTypes, includeVerbs = false } = req.body\n \n const results = await brainy.searchText(query, k, {\n nounTypes,\n includeVerbs\n })\n \n res.json({\n results,\n query: {\n text: query,\n k,\n nounTypes,\n includeVerbs\n },\n timestamp: new Date().toISOString()\n })\n } catch (error) {\n console.error('Text search failed:', error)\n res.status(500).json({\n error: 'Text search failed',\n message: (error as Error).message\n })\n }\n})\n\n// Get item by ID\napp.get('/api/item/:id', [\n param('id').isString().isLength({ min: 1, max: 100 }).withMessage('ID must be a string between 1 and 100 characters'),\n handleValidationErrors\n], async (req: express.Request, res: express.Response) => {\n try {\n const brainy = await initializeBrainy()\n const { id } = req.params\n \n const item = await brainy.get(id)\n \n if (!item) {\n return res.status(404).json({\n error: 'Item not found',\n id\n })\n }\n \n res.json({\n item,\n timestamp: new Date().toISOString()\n })\n } catch (error) {\n console.error('Get item failed:', error)\n res.status(500).json({\n error: 'Failed to get item',\n message: (error as Error).message\n })\n }\n})\n\n// Get all items (paginated)\napp.get('/api/items', [\n query('page').optional().isInt({ min: 1 }).withMessage('Page must be a positive integer'),\n query('limit').optional().isInt({ min: 1, max: 100 }).withMessage('Limit must be between 1 and 100'),\n handleValidationErrors\n], async (req: express.Request, res: express.Response) => {\n try {\n const brainy = await initializeBrainy()\n const page = parseInt(req.query.page as string) || 1\n const limit = parseInt(req.query.limit as string) || 20\n \n const allNouns = await brainy.getAllNouns()\n const total = allNouns.length\n const startIndex = (page - 1) * limit\n const endIndex = startIndex + limit\n const items = allNouns.slice(startIndex, endIndex)\n \n res.json({\n items,\n pagination: {\n page,\n limit,\n total,\n totalPages: Math.ceil(total / limit),\n hasNext: endIndex < total,\n hasPrev: page > 1\n },\n timestamp: new Date().toISOString()\n })\n } catch (error) {\n console.error('Get items failed:', error)\n res.status(500).json({\n error: 'Failed to get items',\n message: (error as Error).message\n })\n }\n})\n\n// Find similar items\napp.post('/api/similar/:id', [\n param('id').isString().isLength({ min: 1, max: 100 }).withMessage('ID must be a string between 1 and 100 characters'),\n body('k').optional().isInt({ min: 1, max: 100 }).withMessage('k must be between 1 and 100'),\n body('includeVerbs').optional().isBoolean().withMessage('includeVerbs must be boolean'),\n handleValidationErrors\n], async (req: express.Request, res: express.Response) => {\n try {\n const brainy = await initializeBrainy()\n const { id } = req.params\n const { k = 10, includeVerbs = false } = req.body\n \n const results = await brainy.findSimilar(id, {\n limit: k,\n includeVerbs\n })\n \n res.json({\n results,\n query: {\n id,\n k,\n includeVerbs\n },\n timestamp: new Date().toISOString()\n })\n } catch (error) {\n console.error('Find similar failed:', error)\n res.status(500).json({\n error: 'Failed to find similar items',\n message: (error as Error).message\n })\n }\n})\n\n// 404 handler\napp.use('*', (req, res) => {\n res.status(404).json({\n error: 'Endpoint not found',\n path: req.originalUrl,\n method: req.method\n })\n})\n\n// Global error handler\napp.use((err: Error, req: express.Request, res: express.Response, next: express.NextFunction) => {\n console.error('Unhandled error:', err)\n res.status(500).json({\n error: 'Internal server error',\n message: process.env.NODE_ENV === 'development' ? err.message : 'Something went wrong'\n })\n})\n\n// Graceful shutdown\nprocess.on('SIGTERM', async () => {\n console.log('SIGTERM received, shutting down gracefully...')\n if (brainyInstance) {\n await brainyInstance.shutDown()\n }\n process.exit(0)\n})\n\nprocess.on('SIGINT', async () => {\n console.log('SIGINT received, shutting down gracefully...')\n if (brainyInstance) {\n await brainyInstance.shutDown()\n }\n process.exit(0)\n})\n\n// Start server\nasync function startServer() {\n try {\n // Initialize Brainy on startup\n await initializeBrainy()\n \n app.listen(Number(PORT), HOST, () => {\n console.log(`🚀 Brainy Web Service started`)\n console.log(`📍 Server running on http://${HOST}:${PORT}`)\n console.log(`📊 API documentation available at http://${HOST}:${PORT}/api`)\n console.log(`🔒 Read-only mode: ${brainyInstance?.isReadOnly()}`)\n console.log(`📁 Data path: ${DATA_PATH}`)\n })\n } catch (error) {\n console.error('Failed to start server:', error)\n process.exit(1)\n }\n}\n\n// Start the server\nstartServer().catch(console.error)\n"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/web-service-package/package.json b/web-service-package/package.json index 5885dade..eeec394c 100644 --- a/web-service-package/package.json +++ b/web-service-package/package.json @@ -53,7 +53,7 @@ "url": "git+https://github.com/soulcraft-research/brainy.git" }, "dependencies": { - "@soulcraft/brainy": "^0.15.0", + "@soulcraft/brainy": "^0.24.0", "express": "^4.18.2", "cors": "^2.8.5", "helmet": "^7.1.0", diff --git a/web-service-package/src/server.ts b/web-service-package/src/server.ts index 7b4ab0b1..01c89662 100644 --- a/web-service-package/src/server.ts +++ b/web-service-package/src/server.ts @@ -138,7 +138,6 @@ async function initializeBrainy(): Promise { await storage.init() brainyInstance = new BrainyData({ - dimensions: 384, // Default dimensions, can be overridden storageAdapter: storage, distanceFunction: cosineDistance }) @@ -150,7 +149,6 @@ async function initializeBrainy(): Promise { const storage = await createStorage(storageOptions) brainyInstance = new BrainyData({ - dimensions: 384, // Default dimensions, can be overridden storageAdapter: storage, distanceFunction: cosineDistance })