@soulcraft/brainy 2.15.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/README.md +249 -152
- package/dist/api/ConfigAPI.d.ts +67 -0
- package/dist/api/ConfigAPI.js +166 -0
- package/dist/api/DataAPI.d.ts +123 -0
- package/dist/api/DataAPI.js +391 -0
- package/dist/api/SecurityAPI.d.ts +50 -0
- package/dist/api/SecurityAPI.js +139 -0
- package/dist/api/UniversalImportAPI.d.ts +134 -0
- package/dist/api/UniversalImportAPI.js +615 -0
- package/dist/augmentationManager.js +12 -7
- package/dist/augmentationPipeline.d.ts +0 -61
- package/dist/augmentationPipeline.js +0 -87
- package/dist/augmentationRegistry.d.ts +1 -1
- package/dist/augmentationRegistry.js +1 -1
- package/dist/augmentations/apiServerAugmentation.d.ts +27 -1
- package/dist/augmentations/apiServerAugmentation.js +288 -7
- package/dist/augmentations/auditLogAugmentation.d.ts +109 -0
- package/dist/augmentations/auditLogAugmentation.js +358 -0
- package/dist/augmentations/batchProcessingAugmentation.d.ts +3 -2
- package/dist/augmentations/batchProcessingAugmentation.js +123 -22
- package/dist/augmentations/brainyAugmentation.d.ts +87 -8
- package/dist/augmentations/brainyAugmentation.js +159 -2
- package/dist/augmentations/cacheAugmentation.d.ts +6 -5
- package/dist/augmentations/cacheAugmentation.js +113 -17
- package/dist/augmentations/conduitAugmentations.d.ts +2 -2
- package/dist/augmentations/conduitAugmentations.js +2 -2
- package/dist/augmentations/configResolver.d.ts +122 -0
- package/dist/augmentations/configResolver.js +440 -0
- package/dist/augmentations/connectionPoolAugmentation.d.ts +3 -1
- package/dist/augmentations/connectionPoolAugmentation.js +37 -12
- package/dist/augmentations/defaultAugmentations.d.ts +9 -11
- package/dist/augmentations/defaultAugmentations.js +4 -11
- package/dist/augmentations/discovery/catalogDiscovery.d.ts +142 -0
- package/dist/augmentations/discovery/catalogDiscovery.js +249 -0
- package/dist/augmentations/discovery/localDiscovery.d.ts +84 -0
- package/dist/augmentations/discovery/localDiscovery.js +246 -0
- package/dist/augmentations/discovery/runtimeLoader.d.ts +97 -0
- package/dist/augmentations/discovery/runtimeLoader.js +337 -0
- package/dist/augmentations/discovery.d.ts +152 -0
- package/dist/augmentations/discovery.js +441 -0
- package/dist/augmentations/display/intelligentComputation.d.ts +1 -1
- package/dist/augmentations/display/intelligentComputation.js +4 -4
- package/dist/augmentations/entityRegistryAugmentation.d.ts +3 -1
- package/dist/augmentations/entityRegistryAugmentation.js +5 -1
- package/dist/augmentations/indexAugmentation.d.ts +3 -3
- package/dist/augmentations/indexAugmentation.js +2 -2
- package/dist/augmentations/intelligentVerbScoringAugmentation.d.ts +22 -6
- package/dist/augmentations/intelligentVerbScoringAugmentation.js +106 -23
- package/dist/augmentations/manifest.d.ts +176 -0
- package/dist/augmentations/manifest.js +8 -0
- package/dist/augmentations/marketplace/AugmentationMarketplace.d.ts +168 -0
- package/dist/augmentations/marketplace/AugmentationMarketplace.js +329 -0
- package/dist/augmentations/marketplace/cli.d.ts +47 -0
- package/dist/augmentations/marketplace/cli.js +265 -0
- package/dist/augmentations/metricsAugmentation.d.ts +3 -3
- package/dist/augmentations/metricsAugmentation.js +2 -2
- package/dist/augmentations/monitoringAugmentation.d.ts +3 -3
- package/dist/augmentations/monitoringAugmentation.js +2 -2
- package/dist/augmentations/neuralImport.d.ts +1 -1
- package/dist/augmentations/rateLimitAugmentation.d.ts +82 -0
- package/dist/augmentations/rateLimitAugmentation.js +321 -0
- package/dist/augmentations/requestDeduplicatorAugmentation.d.ts +2 -2
- package/dist/augmentations/requestDeduplicatorAugmentation.js +1 -1
- package/dist/augmentations/storageAugmentation.d.ts +1 -1
- package/dist/augmentations/storageAugmentation.js +2 -2
- package/dist/augmentations/storageAugmentations.d.ts +37 -8
- package/dist/augmentations/storageAugmentations.js +204 -15
- package/dist/augmentations/synapseAugmentation.d.ts +1 -1
- package/dist/augmentations/synapseAugmentation.js +35 -16
- package/dist/augmentations/typeMatching/intelligentTypeMatcher.d.ts +39 -59
- package/dist/augmentations/typeMatching/intelligentTypeMatcher.js +103 -389
- package/dist/augmentations/universalDisplayAugmentation.d.ts +2 -2
- package/dist/augmentations/universalDisplayAugmentation.js +2 -2
- package/dist/brainy-unified.d.ts +106 -0
- package/dist/brainy-unified.js +327 -0
- package/dist/brainy.d.ts +273 -0
- package/dist/brainy.js +1181 -0
- package/dist/brainyData.d.ts +29 -72
- package/dist/brainyData.js +350 -304
- package/dist/brainyDataV3.d.ts +186 -0
- package/dist/brainyDataV3.js +337 -0
- package/dist/browserFramework.d.ts +6 -6
- package/dist/browserFramework.js +11 -8
- package/dist/browserFramework.minimal.d.ts +5 -5
- package/dist/browserFramework.minimal.js +11 -8
- package/dist/config/index.d.ts +2 -2
- package/dist/config/index.js +3 -3
- package/dist/config/modelAutoConfig.d.ts +6 -7
- package/dist/config/modelAutoConfig.js +17 -76
- package/dist/cortex/backupRestore.d.ts +2 -2
- package/dist/cortex/backupRestore.js +85 -27
- package/dist/cortex/healthCheck.d.ts +2 -2
- package/dist/cortex/neuralImport.d.ts +2 -2
- package/dist/cortex/neuralImport.js +18 -13
- package/dist/cortex/performanceMonitor.d.ts +2 -2
- package/dist/critical/model-guardian.d.ts +4 -0
- package/dist/critical/model-guardian.js +31 -11
- package/dist/demo.d.ts +4 -4
- package/dist/demo.js +7 -7
- package/dist/distributed/cacheSync.d.ts +112 -0
- package/dist/distributed/cacheSync.js +265 -0
- package/dist/distributed/coordinator.d.ts +193 -0
- package/dist/distributed/coordinator.js +548 -0
- package/dist/distributed/httpTransport.d.ts +120 -0
- package/dist/distributed/httpTransport.js +446 -0
- package/dist/distributed/index.d.ts +8 -0
- package/dist/distributed/index.js +5 -0
- package/dist/distributed/networkTransport.d.ts +132 -0
- package/dist/distributed/networkTransport.js +633 -0
- package/dist/distributed/queryPlanner.d.ts +104 -0
- package/dist/distributed/queryPlanner.js +327 -0
- package/dist/distributed/readWriteSeparation.d.ts +134 -0
- package/dist/distributed/readWriteSeparation.js +350 -0
- package/dist/distributed/shardManager.d.ts +114 -0
- package/dist/distributed/shardManager.js +357 -0
- package/dist/distributed/shardMigration.d.ts +110 -0
- package/dist/distributed/shardMigration.js +289 -0
- package/dist/distributed/storageDiscovery.d.ts +160 -0
- package/dist/distributed/storageDiscovery.js +551 -0
- package/dist/embeddings/EmbeddingManager.d.ts +0 -4
- package/dist/embeddings/EmbeddingManager.js +21 -26
- package/dist/errors/brainyError.d.ts +5 -1
- package/dist/errors/brainyError.js +12 -0
- package/dist/examples/basicUsage.js +3 -3
- package/dist/graph/graphAdjacencyIndex.d.ts +96 -0
- package/dist/graph/graphAdjacencyIndex.js +288 -0
- package/dist/graph/pathfinding.js +4 -2
- package/dist/hnsw/scaledHNSWSystem.js +11 -2
- package/dist/importManager.js +6 -3
- package/dist/index.d.ts +12 -21
- package/dist/index.js +14 -22
- package/dist/mcp/brainyMCPAdapter.d.ts +4 -4
- package/dist/mcp/brainyMCPAdapter.js +5 -5
- package/dist/mcp/brainyMCPService.d.ts +3 -3
- package/dist/mcp/brainyMCPService.js +3 -11
- package/dist/mcp/mcpAugmentationToolset.js +20 -30
- package/dist/neural/embeddedPatterns.d.ts +1 -1
- package/dist/neural/embeddedPatterns.js +2 -2
- package/dist/neural/entityExtractor.d.ts +65 -0
- package/dist/neural/entityExtractor.js +316 -0
- package/dist/neural/improvedNeuralAPI.js +90 -79
- package/dist/neural/naturalLanguageProcessor.d.ts +155 -10
- package/dist/neural/naturalLanguageProcessor.js +941 -66
- package/dist/neural/naturalLanguageProcessorStatic.d.ts +2 -2
- package/dist/neural/naturalLanguageProcessorStatic.js +3 -3
- package/dist/neural/neuralAPI.js +8 -2
- package/dist/neural/patternLibrary.d.ts +57 -3
- package/dist/neural/patternLibrary.js +348 -13
- package/dist/neural/staticPatternMatcher.d.ts +2 -2
- package/dist/neural/staticPatternMatcher.js +2 -2
- package/dist/shared/default-augmentations.d.ts +3 -3
- package/dist/shared/default-augmentations.js +5 -5
- package/dist/storage/adapters/fileSystemStorage.d.ts +4 -0
- package/dist/storage/adapters/fileSystemStorage.js +54 -1
- package/dist/storage/adapters/memoryStorage.js +13 -8
- package/dist/storage/backwardCompatibility.d.ts +10 -78
- package/dist/storage/backwardCompatibility.js +17 -132
- package/dist/storage/baseStorage.d.ts +6 -0
- package/dist/storage/baseStorage.js +17 -0
- package/dist/storage/cacheManager.js +2 -2
- package/dist/storage/readOnlyOptimizations.js +8 -3
- package/dist/streaming/pipeline.d.ts +154 -0
- package/dist/streaming/pipeline.js +551 -0
- package/dist/triple/TripleIntelligence.d.ts +25 -110
- package/dist/triple/TripleIntelligence.js +4 -574
- package/dist/triple/TripleIntelligenceSystem.d.ts +159 -0
- package/dist/triple/TripleIntelligenceSystem.js +519 -0
- package/dist/types/apiTypes.d.ts +278 -0
- package/dist/types/apiTypes.js +33 -0
- package/dist/types/brainy.types.d.ts +308 -0
- package/dist/types/brainy.types.js +8 -0
- package/dist/types/brainyDataInterface.d.ts +3 -3
- package/dist/types/brainyDataInterface.js +2 -2
- package/dist/types/graphTypes.js +2 -2
- package/dist/utils/cacheAutoConfig.d.ts +3 -3
- package/dist/utils/embedding.js +8 -14
- package/dist/utils/enhancedLogger.d.ts +104 -0
- package/dist/utils/enhancedLogger.js +232 -0
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/intelligentTypeMapper.d.ts +60 -0
- package/dist/utils/intelligentTypeMapper.js +349 -0
- package/dist/utils/metadataIndex.d.ts +118 -1
- package/dist/utils/metadataIndex.js +539 -16
- package/dist/utils/paramValidation.d.ts +39 -0
- package/dist/utils/paramValidation.js +192 -0
- package/dist/utils/rateLimiter.d.ts +160 -0
- package/dist/utils/rateLimiter.js +271 -0
- package/dist/utils/statistics.d.ts +4 -4
- package/dist/utils/statistics.js +3 -3
- package/dist/utils/structuredLogger.d.ts +146 -0
- package/dist/utils/structuredLogger.js +394 -0
- package/dist/utils/textEncoding.js +2 -1
- package/dist/utils/typeValidation.d.ts +34 -0
- package/dist/utils/typeValidation.js +247 -0
- package/package.json +14 -6
- package/scripts/download-models.cjs +6 -15
- package/dist/augmentations/walAugmentation.d.ts +0 -111
- package/dist/augmentations/walAugmentation.js +0 -519
- package/dist/chat/BrainyChat.d.ts +0 -121
- package/dist/chat/BrainyChat.js +0 -396
- package/dist/chat/ChatCLI.d.ts +0 -61
- package/dist/chat/ChatCLI.js +0 -351
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP + SSE Transport for Zero-Config Distributed Brainy
|
|
3
|
+
* Simple, reliable, works everywhere - no WebSocket complexity!
|
|
4
|
+
* REAL PRODUCTION CODE - Handles millions of operations
|
|
5
|
+
*/
|
|
6
|
+
import * as http from 'http';
|
|
7
|
+
import * as https from 'https';
|
|
8
|
+
import { EventEmitter } from 'events';
|
|
9
|
+
import * as net from 'net';
|
|
10
|
+
import { URL } from 'url';
|
|
11
|
+
export class HTTPTransport extends EventEmitter {
|
|
12
|
+
constructor(nodeId) {
|
|
13
|
+
super();
|
|
14
|
+
this.server = null;
|
|
15
|
+
this.port = 0;
|
|
16
|
+
this.endpoints = new Map(); // nodeId -> endpoint
|
|
17
|
+
this.pendingRequests = new Map();
|
|
18
|
+
this.sseClients = new Map();
|
|
19
|
+
this.messageHandlers = new Map();
|
|
20
|
+
this.isRunning = false;
|
|
21
|
+
this.REQUEST_TIMEOUT = 30000; // 30 seconds
|
|
22
|
+
this.SSE_HEARTBEAT_INTERVAL = 15000; // 15 seconds
|
|
23
|
+
this.sseHeartbeatTimer = null;
|
|
24
|
+
this.nodeId = nodeId;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Start HTTP server with automatic port selection
|
|
28
|
+
*/
|
|
29
|
+
async start() {
|
|
30
|
+
if (this.isRunning)
|
|
31
|
+
return this.port;
|
|
32
|
+
// Create HTTP server with all handlers
|
|
33
|
+
this.server = http.createServer(async (req, res) => {
|
|
34
|
+
// Enable CORS for browser compatibility
|
|
35
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
36
|
+
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
|
|
37
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
|
38
|
+
if (req.method === 'OPTIONS') {
|
|
39
|
+
res.writeHead(204);
|
|
40
|
+
res.end();
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const url = new URL(req.url || '/', `http://${req.headers.host}`);
|
|
44
|
+
try {
|
|
45
|
+
// Route requests
|
|
46
|
+
if (url.pathname === '/health') {
|
|
47
|
+
await this.handleHealth(req, res);
|
|
48
|
+
}
|
|
49
|
+
else if (url.pathname === '/rpc') {
|
|
50
|
+
await this.handleRPC(req, res);
|
|
51
|
+
}
|
|
52
|
+
else if (url.pathname === '/events') {
|
|
53
|
+
await this.handleSSE(req, res);
|
|
54
|
+
}
|
|
55
|
+
else if (url.pathname.startsWith('/stream/')) {
|
|
56
|
+
await this.handleStream(req, res, url);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
res.writeHead(404);
|
|
60
|
+
res.end('Not Found');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
console.error(`[${this.nodeId}] Request error:`, err);
|
|
65
|
+
res.writeHead(500);
|
|
66
|
+
res.end('Internal Server Error');
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
// Find available port
|
|
70
|
+
this.port = await this.findAvailablePort();
|
|
71
|
+
// Start server
|
|
72
|
+
await new Promise((resolve, reject) => {
|
|
73
|
+
this.server.listen(this.port, () => {
|
|
74
|
+
console.log(`[${this.nodeId}] HTTP transport listening on port ${this.port}`);
|
|
75
|
+
resolve();
|
|
76
|
+
});
|
|
77
|
+
this.server.on('error', reject);
|
|
78
|
+
});
|
|
79
|
+
this.isRunning = true;
|
|
80
|
+
// Start SSE heartbeat
|
|
81
|
+
this.startSSEHeartbeat();
|
|
82
|
+
this.emit('started', this.port);
|
|
83
|
+
return this.port;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Stop HTTP server
|
|
87
|
+
*/
|
|
88
|
+
async stop() {
|
|
89
|
+
if (!this.isRunning)
|
|
90
|
+
return;
|
|
91
|
+
this.isRunning = false;
|
|
92
|
+
// Stop SSE heartbeat
|
|
93
|
+
if (this.sseHeartbeatTimer) {
|
|
94
|
+
clearInterval(this.sseHeartbeatTimer);
|
|
95
|
+
this.sseHeartbeatTimer = null;
|
|
96
|
+
}
|
|
97
|
+
// Close all SSE connections
|
|
98
|
+
for (const client of this.sseClients.values()) {
|
|
99
|
+
client.response.end();
|
|
100
|
+
}
|
|
101
|
+
this.sseClients.clear();
|
|
102
|
+
// Cancel pending requests
|
|
103
|
+
for (const pending of this.pendingRequests.values()) {
|
|
104
|
+
clearTimeout(pending.timeout);
|
|
105
|
+
pending.reject(new Error('Transport shutting down'));
|
|
106
|
+
}
|
|
107
|
+
this.pendingRequests.clear();
|
|
108
|
+
// Close server
|
|
109
|
+
if (this.server) {
|
|
110
|
+
await new Promise(resolve => {
|
|
111
|
+
this.server.close(() => resolve());
|
|
112
|
+
});
|
|
113
|
+
this.server = null;
|
|
114
|
+
}
|
|
115
|
+
this.emit('stopped');
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Register a node endpoint
|
|
119
|
+
*/
|
|
120
|
+
registerEndpoint(nodeId, endpoint) {
|
|
121
|
+
this.endpoints.set(nodeId, endpoint);
|
|
122
|
+
this.emit('endpointRegistered', { nodeId, endpoint });
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Register RPC method handler
|
|
126
|
+
*/
|
|
127
|
+
registerHandler(method, handler) {
|
|
128
|
+
this.messageHandlers.set(method, handler);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Call RPC method on remote node
|
|
132
|
+
*/
|
|
133
|
+
async call(nodeId, method, params) {
|
|
134
|
+
const endpoint = this.endpoints.get(nodeId);
|
|
135
|
+
if (!endpoint) {
|
|
136
|
+
throw new Error(`No endpoint registered for node ${nodeId}`);
|
|
137
|
+
}
|
|
138
|
+
const message = {
|
|
139
|
+
id: this.generateId(),
|
|
140
|
+
method,
|
|
141
|
+
params,
|
|
142
|
+
timestamp: Date.now(),
|
|
143
|
+
from: this.nodeId,
|
|
144
|
+
to: nodeId
|
|
145
|
+
};
|
|
146
|
+
// Send HTTP request
|
|
147
|
+
const response = await this.sendHTTPRequest(endpoint, '/rpc', message);
|
|
148
|
+
if (response.error) {
|
|
149
|
+
throw new Error(response.error.message);
|
|
150
|
+
}
|
|
151
|
+
return response.result;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Broadcast to all SSE clients
|
|
155
|
+
*/
|
|
156
|
+
broadcast(event, data) {
|
|
157
|
+
const message = JSON.stringify({ event, data, timestamp: Date.now() });
|
|
158
|
+
for (const [clientId, client] of this.sseClients.entries()) {
|
|
159
|
+
try {
|
|
160
|
+
client.response.write(`data: ${message}\n\n`);
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
// Client disconnected
|
|
164
|
+
console.debug(`[${this.nodeId}] SSE client ${clientId} disconnected`);
|
|
165
|
+
this.sseClients.delete(clientId);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Handle health check
|
|
171
|
+
*/
|
|
172
|
+
async handleHealth(req, res) {
|
|
173
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
174
|
+
res.end(JSON.stringify({
|
|
175
|
+
status: 'healthy',
|
|
176
|
+
nodeId: this.nodeId,
|
|
177
|
+
uptime: process.uptime(),
|
|
178
|
+
memory: process.memoryUsage(),
|
|
179
|
+
connections: this.sseClients.size
|
|
180
|
+
}));
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Handle RPC requests
|
|
184
|
+
*/
|
|
185
|
+
async handleRPC(req, res) {
|
|
186
|
+
if (req.method !== 'POST') {
|
|
187
|
+
res.writeHead(405);
|
|
188
|
+
res.end('Method Not Allowed');
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
// Read body
|
|
192
|
+
const body = await this.readBody(req);
|
|
193
|
+
let message;
|
|
194
|
+
try {
|
|
195
|
+
message = JSON.parse(body);
|
|
196
|
+
}
|
|
197
|
+
catch (err) {
|
|
198
|
+
res.writeHead(400);
|
|
199
|
+
res.end('Invalid JSON');
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
// Handle the RPC call
|
|
203
|
+
const response = {
|
|
204
|
+
id: message.id,
|
|
205
|
+
timestamp: Date.now()
|
|
206
|
+
};
|
|
207
|
+
try {
|
|
208
|
+
const handler = this.messageHandlers.get(message.method);
|
|
209
|
+
if (!handler) {
|
|
210
|
+
throw new Error(`Method ${message.method} not found`);
|
|
211
|
+
}
|
|
212
|
+
response.result = await handler(message.params, message.from);
|
|
213
|
+
}
|
|
214
|
+
catch (err) {
|
|
215
|
+
response.error = {
|
|
216
|
+
code: -32603,
|
|
217
|
+
message: err.message,
|
|
218
|
+
data: err.stack
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
222
|
+
res.end(JSON.stringify(response));
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Handle SSE connections for real-time updates
|
|
226
|
+
*/
|
|
227
|
+
async handleSSE(req, res) {
|
|
228
|
+
// Setup SSE headers
|
|
229
|
+
res.writeHead(200, {
|
|
230
|
+
'Content-Type': 'text/event-stream',
|
|
231
|
+
'Cache-Control': 'no-cache',
|
|
232
|
+
'Connection': 'keep-alive',
|
|
233
|
+
'X-Accel-Buffering': 'no' // Disable Nginx buffering
|
|
234
|
+
});
|
|
235
|
+
// Send initial connection event
|
|
236
|
+
const clientId = this.generateId();
|
|
237
|
+
res.write(`data: ${JSON.stringify({
|
|
238
|
+
event: 'connected',
|
|
239
|
+
clientId,
|
|
240
|
+
nodeId: this.nodeId
|
|
241
|
+
})}\n\n`);
|
|
242
|
+
// Store client
|
|
243
|
+
this.sseClients.set(clientId, {
|
|
244
|
+
id: clientId,
|
|
245
|
+
response: res,
|
|
246
|
+
lastPing: Date.now()
|
|
247
|
+
});
|
|
248
|
+
// Handle client disconnect
|
|
249
|
+
req.on('close', () => {
|
|
250
|
+
this.sseClients.delete(clientId);
|
|
251
|
+
this.emit('sseDisconnected', clientId);
|
|
252
|
+
});
|
|
253
|
+
this.emit('sseConnected', clientId);
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Handle streaming data (for shard migration)
|
|
257
|
+
*/
|
|
258
|
+
async handleStream(req, res, url) {
|
|
259
|
+
const streamId = url.pathname.split('/').pop();
|
|
260
|
+
if (req.method === 'POST') {
|
|
261
|
+
// Receiving stream
|
|
262
|
+
await this.handleStreamUpload(req, res, streamId);
|
|
263
|
+
}
|
|
264
|
+
else if (req.method === 'GET') {
|
|
265
|
+
// Sending stream
|
|
266
|
+
await this.handleStreamDownload(req, res, streamId);
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
res.writeHead(405);
|
|
270
|
+
res.end('Method Not Allowed');
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Handle stream upload (receiving data)
|
|
275
|
+
*/
|
|
276
|
+
async handleStreamUpload(req, res, streamId) {
|
|
277
|
+
const chunks = [];
|
|
278
|
+
let totalSize = 0;
|
|
279
|
+
req.on('data', (chunk) => {
|
|
280
|
+
chunks.push(chunk);
|
|
281
|
+
totalSize += chunk.length;
|
|
282
|
+
// Emit progress
|
|
283
|
+
this.emit('streamProgress', {
|
|
284
|
+
streamId,
|
|
285
|
+
type: 'upload',
|
|
286
|
+
bytes: totalSize
|
|
287
|
+
});
|
|
288
|
+
});
|
|
289
|
+
req.on('end', () => {
|
|
290
|
+
const data = Buffer.concat(chunks);
|
|
291
|
+
// Process the streamed data
|
|
292
|
+
this.emit('streamComplete', {
|
|
293
|
+
streamId,
|
|
294
|
+
type: 'upload',
|
|
295
|
+
data,
|
|
296
|
+
size: totalSize
|
|
297
|
+
});
|
|
298
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
299
|
+
res.end(JSON.stringify({
|
|
300
|
+
success: true,
|
|
301
|
+
streamId,
|
|
302
|
+
size: totalSize
|
|
303
|
+
}));
|
|
304
|
+
});
|
|
305
|
+
req.on('error', (err) => {
|
|
306
|
+
console.error(`[${this.nodeId}] Stream upload error:`, err);
|
|
307
|
+
res.writeHead(500);
|
|
308
|
+
res.end('Stream Error');
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Handle stream download (sending data)
|
|
313
|
+
*/
|
|
314
|
+
async handleStreamDownload(req, res, streamId) {
|
|
315
|
+
// Stream download not yet implemented
|
|
316
|
+
// Return error response instead of fake data
|
|
317
|
+
res.writeHead(501, {
|
|
318
|
+
'Content-Type': 'application/json'
|
|
319
|
+
});
|
|
320
|
+
res.end(JSON.stringify({
|
|
321
|
+
error: 'Stream download not implemented',
|
|
322
|
+
message: 'This feature is not yet available in the current version',
|
|
323
|
+
streamId
|
|
324
|
+
}));
|
|
325
|
+
this.emit('streamError', {
|
|
326
|
+
streamId,
|
|
327
|
+
type: 'download',
|
|
328
|
+
error: 'Not implemented'
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Send HTTP request to another node
|
|
333
|
+
*/
|
|
334
|
+
async sendHTTPRequest(endpoint, path, data) {
|
|
335
|
+
return new Promise((resolve, reject) => {
|
|
336
|
+
const url = new URL(path, endpoint);
|
|
337
|
+
const options = {
|
|
338
|
+
method: 'POST',
|
|
339
|
+
headers: {
|
|
340
|
+
'Content-Type': 'application/json'
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
const proto = url.protocol === 'https:' ? https : http;
|
|
344
|
+
const req = proto.request(url, options, (res) => {
|
|
345
|
+
let body = '';
|
|
346
|
+
res.on('data', chunk => body += chunk);
|
|
347
|
+
res.on('end', () => {
|
|
348
|
+
try {
|
|
349
|
+
const response = JSON.parse(body);
|
|
350
|
+
resolve(response);
|
|
351
|
+
}
|
|
352
|
+
catch (err) {
|
|
353
|
+
reject(new Error(`Invalid response: ${body}`));
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
});
|
|
357
|
+
req.on('error', reject);
|
|
358
|
+
req.on('timeout', () => {
|
|
359
|
+
req.destroy();
|
|
360
|
+
reject(new Error('Request timeout'));
|
|
361
|
+
});
|
|
362
|
+
req.setTimeout(this.REQUEST_TIMEOUT);
|
|
363
|
+
req.write(JSON.stringify(data));
|
|
364
|
+
req.end();
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Read request body
|
|
369
|
+
*/
|
|
370
|
+
readBody(req) {
|
|
371
|
+
return new Promise((resolve, reject) => {
|
|
372
|
+
let body = '';
|
|
373
|
+
req.on('data', chunk => body += chunk);
|
|
374
|
+
req.on('end', () => resolve(body));
|
|
375
|
+
req.on('error', reject);
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Find an available port
|
|
380
|
+
*/
|
|
381
|
+
async findAvailablePort(startPort = 7947) {
|
|
382
|
+
const checkPort = (port) => {
|
|
383
|
+
return new Promise(resolve => {
|
|
384
|
+
const server = net.createServer();
|
|
385
|
+
server.once('error', () => resolve(false));
|
|
386
|
+
server.once('listening', () => {
|
|
387
|
+
server.close();
|
|
388
|
+
resolve(true);
|
|
389
|
+
});
|
|
390
|
+
server.listen(port);
|
|
391
|
+
});
|
|
392
|
+
};
|
|
393
|
+
// Try preferred port first
|
|
394
|
+
if (await checkPort(startPort)) {
|
|
395
|
+
return startPort;
|
|
396
|
+
}
|
|
397
|
+
// Find random available port
|
|
398
|
+
return new Promise((resolve, reject) => {
|
|
399
|
+
const server = net.createServer();
|
|
400
|
+
server.once('error', reject);
|
|
401
|
+
server.once('listening', () => {
|
|
402
|
+
const port = server.address().port;
|
|
403
|
+
server.close(() => resolve(port));
|
|
404
|
+
});
|
|
405
|
+
server.listen(0); // 0 = random available port
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Start SSE heartbeat to keep connections alive
|
|
410
|
+
*/
|
|
411
|
+
startSSEHeartbeat() {
|
|
412
|
+
this.sseHeartbeatTimer = setInterval(() => {
|
|
413
|
+
const now = Date.now();
|
|
414
|
+
const ping = JSON.stringify({ event: 'ping', timestamp: now });
|
|
415
|
+
for (const [clientId, client] of this.sseClients.entries()) {
|
|
416
|
+
try {
|
|
417
|
+
client.response.write(`: ping\n\n`); // SSE comment for keep-alive
|
|
418
|
+
client.lastPing = now;
|
|
419
|
+
}
|
|
420
|
+
catch (err) {
|
|
421
|
+
// Client disconnected
|
|
422
|
+
this.sseClients.delete(clientId);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
}, this.SSE_HEARTBEAT_INTERVAL);
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Generate unique ID
|
|
429
|
+
*/
|
|
430
|
+
generateId() {
|
|
431
|
+
return `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Get connected nodes count
|
|
435
|
+
*/
|
|
436
|
+
getConnectionCount() {
|
|
437
|
+
return this.endpoints.size;
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Get SSE client count
|
|
441
|
+
*/
|
|
442
|
+
getSSEClientCount() {
|
|
443
|
+
return this.sseClients.size;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
//# sourceMappingURL=httpTransport.js.map
|
|
@@ -6,5 +6,13 @@ export { HashPartitioner, AffinityPartitioner } from './hashPartitioner.js';
|
|
|
6
6
|
export { BaseOperationalMode, ReaderMode, WriterMode, HybridMode, OperationalModeFactory } from './operationalModes.js';
|
|
7
7
|
export { DomainDetector } from './domainDetector.js';
|
|
8
8
|
export { HealthMonitor } from './healthMonitor.js';
|
|
9
|
+
export { DistributedCoordinator, createCoordinator } from './coordinator.js';
|
|
10
|
+
export { ShardManager, createShardManager } from './shardManager.js';
|
|
11
|
+
export { CacheSync, createCacheSync } from './cacheSync.js';
|
|
12
|
+
export { ReadWriteSeparation, createReadWriteSeparation } from './readWriteSeparation.js';
|
|
9
13
|
export type { HealthMetrics, HealthStatus } from './healthMonitor.js';
|
|
10
14
|
export type { DomainPattern } from './domainDetector.js';
|
|
15
|
+
export type { NodeInfo, CoordinatorConfig, ConsensusState } from './coordinator.js';
|
|
16
|
+
export type { ShardConfig, Shard, ShardAssignment } from './shardManager.js';
|
|
17
|
+
export type { CacheSyncConfig, CacheEntry, SyncMessage } from './cacheSync.js';
|
|
18
|
+
export type { ReplicationConfig, WriteOperation, ReplicationLog } from './readWriteSeparation.js';
|
|
@@ -6,4 +6,9 @@ export { HashPartitioner, AffinityPartitioner } from './hashPartitioner.js';
|
|
|
6
6
|
export { BaseOperationalMode, ReaderMode, WriterMode, HybridMode, OperationalModeFactory } from './operationalModes.js';
|
|
7
7
|
export { DomainDetector } from './domainDetector.js';
|
|
8
8
|
export { HealthMonitor } from './healthMonitor.js';
|
|
9
|
+
// New distributed scaling components
|
|
10
|
+
export { DistributedCoordinator, createCoordinator } from './coordinator.js';
|
|
11
|
+
export { ShardManager, createShardManager } from './shardManager.js';
|
|
12
|
+
export { CacheSync, createCacheSync } from './cacheSync.js';
|
|
13
|
+
export { ReadWriteSeparation, createReadWriteSeparation } from './readWriteSeparation.js';
|
|
9
14
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Network Transport Layer for Distributed Brainy
|
|
3
|
+
* Uses WebSocket + HTTP for maximum compatibility
|
|
4
|
+
*/
|
|
5
|
+
import { EventEmitter } from 'events';
|
|
6
|
+
export interface NetworkMessage {
|
|
7
|
+
type: string;
|
|
8
|
+
from: string;
|
|
9
|
+
to?: string;
|
|
10
|
+
data: any;
|
|
11
|
+
timestamp: number;
|
|
12
|
+
id: string;
|
|
13
|
+
}
|
|
14
|
+
export interface NodeEndpoint {
|
|
15
|
+
nodeId: string;
|
|
16
|
+
host: string;
|
|
17
|
+
httpPort: number;
|
|
18
|
+
wsPort: number;
|
|
19
|
+
lastSeen: number;
|
|
20
|
+
}
|
|
21
|
+
export interface NetworkConfig {
|
|
22
|
+
nodeId?: string;
|
|
23
|
+
host?: string;
|
|
24
|
+
httpPort?: number;
|
|
25
|
+
wsPort?: number;
|
|
26
|
+
seeds?: string[];
|
|
27
|
+
discoveryMethod?: 'seeds' | 'dns' | 'kubernetes' | 'auto';
|
|
28
|
+
enableUDP?: boolean;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Production-ready network transport
|
|
32
|
+
*/
|
|
33
|
+
export declare class NetworkTransport extends EventEmitter {
|
|
34
|
+
private nodeId;
|
|
35
|
+
private config;
|
|
36
|
+
private httpServer?;
|
|
37
|
+
private wsServer;
|
|
38
|
+
private peers;
|
|
39
|
+
private connections;
|
|
40
|
+
private messageHandlers;
|
|
41
|
+
private responseHandlers;
|
|
42
|
+
private isRunning;
|
|
43
|
+
constructor(config: NetworkConfig);
|
|
44
|
+
/**
|
|
45
|
+
* Start network transport
|
|
46
|
+
*/
|
|
47
|
+
start(): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* Stop network transport
|
|
50
|
+
*/
|
|
51
|
+
stop(): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Start HTTP server for REST API and health checks
|
|
54
|
+
*/
|
|
55
|
+
private startHTTPServer;
|
|
56
|
+
/**
|
|
57
|
+
* Start WebSocket server for real-time communication
|
|
58
|
+
*/
|
|
59
|
+
private startWebSocketServer;
|
|
60
|
+
/**
|
|
61
|
+
* Discover peers based on configuration
|
|
62
|
+
*/
|
|
63
|
+
private discoverPeers;
|
|
64
|
+
/**
|
|
65
|
+
* Connect to seed nodes
|
|
66
|
+
*/
|
|
67
|
+
private connectToSeeds;
|
|
68
|
+
/**
|
|
69
|
+
* Discover peers via DNS
|
|
70
|
+
*/
|
|
71
|
+
private discoverViaDNS;
|
|
72
|
+
/**
|
|
73
|
+
* Discover peers via Kubernetes
|
|
74
|
+
*/
|
|
75
|
+
private discoverViaKubernetes;
|
|
76
|
+
/**
|
|
77
|
+
* Connect to a specific node
|
|
78
|
+
*/
|
|
79
|
+
private connectToNode;
|
|
80
|
+
/**
|
|
81
|
+
* Get node information via HTTP
|
|
82
|
+
*/
|
|
83
|
+
private getNodeInfo;
|
|
84
|
+
/**
|
|
85
|
+
* Connect to peer via WebSocket
|
|
86
|
+
*/
|
|
87
|
+
private connectWebSocket;
|
|
88
|
+
/**
|
|
89
|
+
* Start heartbeat to maintain connections
|
|
90
|
+
*/
|
|
91
|
+
private startHeartbeat;
|
|
92
|
+
/**
|
|
93
|
+
* Send message to specific node
|
|
94
|
+
*/
|
|
95
|
+
sendToNode(nodeId: string, type: string, data: any): Promise<any>;
|
|
96
|
+
/**
|
|
97
|
+
* Send via HTTP
|
|
98
|
+
*/
|
|
99
|
+
private sendViaHTTP;
|
|
100
|
+
/**
|
|
101
|
+
* Broadcast to all peers
|
|
102
|
+
*/
|
|
103
|
+
broadcast(type: string, data: any): Promise<void>;
|
|
104
|
+
/**
|
|
105
|
+
* Register message handler
|
|
106
|
+
*/
|
|
107
|
+
onMessage(type: string, handler: (msg: NetworkMessage) => Promise<any>): void;
|
|
108
|
+
/**
|
|
109
|
+
* Get connected peers
|
|
110
|
+
*/
|
|
111
|
+
getPeers(): NodeEndpoint[];
|
|
112
|
+
/**
|
|
113
|
+
* Check if connected
|
|
114
|
+
*/
|
|
115
|
+
isConnected(nodeId: string): boolean;
|
|
116
|
+
/**
|
|
117
|
+
* Generate node ID
|
|
118
|
+
*/
|
|
119
|
+
private generateNodeId;
|
|
120
|
+
/**
|
|
121
|
+
* Generate message ID
|
|
122
|
+
*/
|
|
123
|
+
private generateMessageId;
|
|
124
|
+
/**
|
|
125
|
+
* Get node ID
|
|
126
|
+
*/
|
|
127
|
+
getNodeId(): string;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Create network transport
|
|
131
|
+
*/
|
|
132
|
+
export declare function createNetworkTransport(config: NetworkConfig): NetworkTransport;
|