| | "use strict"; |
| | |
| | |
| | |
| | |
| | |
| | |
| | Object.defineProperty(exports, "__esModule", { value: true }); |
| | exports.RuvectorCluster = void 0; |
| | exports.isClusterAvailable = isClusterAvailable; |
| | exports.createCluster = createCluster; |
| | let clusterModule = null; |
| | let loadError = null; |
| | function getClusterModule() { |
| | if (clusterModule) |
| | return clusterModule; |
| | if (loadError) |
| | throw loadError; |
| | try { |
| | clusterModule = require('@ruvector/cluster'); |
| | return clusterModule; |
| | } |
| | catch (e) { |
| | loadError = new Error(`@ruvector/cluster not installed: ${e.message}\n` + |
| | `Install with: npm install @ruvector/cluster`); |
| | throw loadError; |
| | } |
| | } |
| | function isClusterAvailable() { |
| | try { |
| | getClusterModule(); |
| | return true; |
| | } |
| | catch { |
| | return false; |
| | } |
| | } |
| | |
| | |
| | |
| | class RuvectorCluster { |
| | constructor(config) { |
| | this.isLeader = false; |
| | const cluster = getClusterModule(); |
| | this.nodeId = config.nodeId; |
| | this.inner = new cluster.Cluster({ |
| | nodeId: config.nodeId, |
| | address: config.address, |
| | peers: config.peers ?? [], |
| | shards: config.shards ?? 16, |
| | replicationFactor: config.replicationFactor ?? 2, |
| | }); |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | async start() { |
| | await this.inner.start(); |
| | } |
| | |
| | |
| | |
| | async stop() { |
| | await this.inner.stop(); |
| | } |
| | |
| | |
| | |
| | async join(peerAddress) { |
| | return this.inner.join(peerAddress); |
| | } |
| | |
| | |
| | |
| | async leave() { |
| | await this.inner.leave(); |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | getNodeInfo() { |
| | return this.inner.getNodeInfo(); |
| | } |
| | |
| | |
| | |
| | getNodes() { |
| | return this.inner.getNodes(); |
| | } |
| | |
| | |
| | |
| | isClusterLeader() { |
| | this.isLeader = this.inner.isLeader(); |
| | return this.isLeader; |
| | } |
| | |
| | |
| | |
| | getLeader() { |
| | return this.inner.getLeader(); |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | async put(key, value) { |
| | return this.inner.put(key, JSON.stringify(value)); |
| | } |
| | |
| | |
| | |
| | async get(key) { |
| | const result = await this.inner.get(key); |
| | return result ? JSON.parse(result) : null; |
| | } |
| | |
| | |
| | |
| | async delete(key) { |
| | return this.inner.delete(key); |
| | } |
| | |
| | |
| | |
| | async compareAndSwap(key, expected, newValue) { |
| | return this.inner.compareAndSwap(key, JSON.stringify(expected), JSON.stringify(newValue)); |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | getShards() { |
| | return this.inner.getShards(); |
| | } |
| | |
| | |
| | |
| | getShardForKey(key) { |
| | return this.inner.getShardForKey(key); |
| | } |
| | |
| | |
| | |
| | async rebalance() { |
| | await this.inner.rebalance(); |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | async lock(name, timeout = 30000) { |
| | return this.inner.lock(name, timeout); |
| | } |
| | |
| | |
| | |
| | async unlock(name, token) { |
| | return this.inner.unlock(name, token); |
| | } |
| | |
| | |
| | |
| | async extendLock(name, token, extension = 30000) { |
| | return this.inner.extendLock(name, token, extension); |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | subscribe(channel, callback) { |
| | return this.inner.subscribe(channel, (msg) => { |
| | callback(JSON.parse(msg)); |
| | }); |
| | } |
| | |
| | |
| | |
| | async publish(channel, message) { |
| | return this.inner.publish(channel, JSON.stringify(message)); |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | async registerAgent(agentId, capabilities) { |
| | return this.put(`agent:${agentId}`, { |
| | id: agentId, |
| | capabilities, |
| | node: this.nodeId, |
| | registeredAt: Date.now(), |
| | }); |
| | } |
| | |
| | |
| | |
| | async findAgents(capability) { |
| | const agents = await this.inner.scan('agent:*'); |
| | const matching = []; |
| | for (const key of agents) { |
| | const agent = await this.get(key); |
| | if (agent?.capabilities?.includes(capability)) { |
| | matching.push(agent.id); |
| | } |
| | } |
| | return matching; |
| | } |
| | |
| | |
| | |
| | async assignTask(taskId, agentId, task) { |
| | const assigned = await this.put(`task:${taskId}`, { |
| | id: taskId, |
| | agent: agentId, |
| | task, |
| | status: 'assigned', |
| | assignedAt: Date.now(), |
| | }); |
| | if (assigned) { |
| | await this.publish(`agent:${agentId}:tasks`, { type: 'new_task', taskId }); |
| | } |
| | return assigned; |
| | } |
| | |
| | |
| | |
| | async completeTask(taskId, result) { |
| | const task = await this.get(`task:${taskId}`); |
| | if (!task) |
| | return false; |
| | return this.put(`task:${taskId}`, { |
| | ...task, |
| | status: 'completed', |
| | result, |
| | completedAt: Date.now(), |
| | }); |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | stats() { |
| | return this.inner.stats(); |
| | } |
| | } |
| | exports.RuvectorCluster = RuvectorCluster; |
| | |
| | |
| | |
| | function createCluster(config) { |
| | return new RuvectorCluster(config); |
| | } |
| | exports.default = RuvectorCluster; |
| |
|