UNPKG

@sirmrmarty/n8n-nodes-tmux-orchestrator

Version:

n8n nodes for orchestrating Claude AI agents through tmux sessions

383 lines 10.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.stateManager = exports.StateManager = exports.ThreadSafeQueue = exports.ThreadSafeCounter = exports.ThreadSafeSet = exports.ThreadSafeMap = void 0; const events_1 = require("events"); class ThreadSafeMap extends events_1.EventEmitter { constructor(lockTimeout = 5000) { super(); this.map = new Map(); this.locks = new Set(); this.lockTimeout = lockTimeout; } async acquireLock(key) { const lockId = `${String(key)}_${Date.now()}_${Math.random()}`; const keyStr = String(key); while (this.locks.has(keyStr)) { await new Promise(resolve => setTimeout(resolve, 10)); } this.locks.add(keyStr); setTimeout(() => { if (this.locks.has(keyStr)) { console.warn(`Lock timeout for key ${keyStr}, forcibly releasing`); this.locks.delete(keyStr); } }, this.lockTimeout); return lockId; } releaseLock(key) { this.locks.delete(String(key)); } async safeSet(key, value) { await this.acquireLock(key); try { const oldValue = this.map.get(key); this.map.set(key, value); this.emit('change', { key, oldValue, newValue: value, operation: 'set' }); } finally { this.releaseLock(key); } } safeGet(key) { return this.map.get(key); } async safeDelete(key) { await this.acquireLock(key); try { const oldValue = this.map.get(key); const deleted = this.map.delete(key); if (deleted) { this.emit('change', { key, oldValue, newValue: undefined, operation: 'delete' }); } return deleted; } finally { this.releaseLock(key); } } safeHas(key) { return this.map.has(key); } safeKeys() { return Array.from(this.map.keys()); } safeValues() { return Array.from(this.map.values()); } safeEntries() { return Array.from(this.map.entries()); } safeSize() { return this.map.size; } async safeClear() { const keys = this.safeKeys(); for (const key of keys) { await this.acquireLock(key); } try { this.map.clear(); this.emit('change', { operation: 'clear' }); } finally { for (const key of keys) { this.releaseLock(key); } } } async safeUpdate(key, updateFn) { await this.acquireLock(key); try { const oldValue = this.map.get(key); const newValue = updateFn(oldValue); this.map.set(key, newValue); this.emit('change', { key, oldValue, newValue, operation: 'update' }); return newValue; } finally { this.releaseLock(key); } } async safeComputeIfAbsent(key, computeFn) { await this.acquireLock(key); try { if (this.map.has(key)) { return this.map.get(key); } const value = await Promise.resolve(computeFn()); this.map.set(key, value); this.emit('change', { key, oldValue: undefined, newValue: value, operation: 'compute' }); return value; } finally { this.releaseLock(key); } } } exports.ThreadSafeMap = ThreadSafeMap; class ThreadSafeSet extends events_1.EventEmitter { constructor(lockTimeout = 5000) { super(); this.set = new Set(); this.locks = new Set(); this.lockTimeout = lockTimeout; } async acquireLock() { const lockId = `set_${Date.now()}_${Math.random()}`; while (this.locks.size > 0) { await new Promise(resolve => setTimeout(resolve, 10)); } this.locks.add(lockId); setTimeout(() => { if (this.locks.has(lockId)) { console.warn(`Set lock timeout, forcibly releasing`); this.locks.delete(lockId); } }, this.lockTimeout); } releaseLock() { this.locks.clear(); } async safeAdd(value) { await this.acquireLock(); try { const hadValue = this.set.has(value); this.set.add(value); if (!hadValue) { this.emit('change', { value, operation: 'add' }); } return !hadValue; } finally { this.releaseLock(); } } async safeDelete(value) { await this.acquireLock(); try { const deleted = this.set.delete(value); if (deleted) { this.emit('change', { value, operation: 'delete' }); } return deleted; } finally { this.releaseLock(); } } safeHas(value) { return this.set.has(value); } safeValues() { return Array.from(this.set.values()); } safeSize() { return this.set.size; } async safeClear() { await this.acquireLock(); try { this.set.clear(); this.emit('change', { operation: 'clear' }); } finally { this.releaseLock(); } } } exports.ThreadSafeSet = ThreadSafeSet; class ThreadSafeCounter extends events_1.EventEmitter { constructor() { super(...arguments); this.value = 0; this.lock = false; } async increment(amount = 1) { while (this.lock) { await new Promise(resolve => setTimeout(resolve, 1)); } this.lock = true; try { const oldValue = this.value; this.value += amount; this.emit('change', { oldValue, newValue: this.value, operation: 'increment' }); return this.value; } finally { this.lock = false; } } async decrement(amount = 1) { return this.increment(-amount); } getValue() { return this.value; } async setValue(newValue) { while (this.lock) { await new Promise(resolve => setTimeout(resolve, 1)); } this.lock = true; try { const oldValue = this.value; this.value = newValue; this.emit('change', { oldValue, newValue, operation: 'set' }); return this.value; } finally { this.lock = false; } } async compareAndSwap(expected, newValue) { while (this.lock) { await new Promise(resolve => setTimeout(resolve, 1)); } this.lock = true; try { if (this.value === expected) { const oldValue = this.value; this.value = newValue; this.emit('change', { oldValue, newValue, operation: 'compareAndSwap' }); return true; } return false; } finally { this.lock = false; } } } exports.ThreadSafeCounter = ThreadSafeCounter; class ThreadSafeQueue extends events_1.EventEmitter { constructor() { super(...arguments); this.queue = []; this.lock = false; } async acquireLock() { while (this.lock) { await new Promise(resolve => setTimeout(resolve, 1)); } this.lock = true; } releaseLock() { this.lock = false; } async enqueue(item) { await this.acquireLock(); try { this.queue.push(item); this.emit('enqueue', item); } finally { this.releaseLock(); } } async dequeue() { await this.acquireLock(); try { const item = this.queue.shift(); if (item !== undefined) { this.emit('dequeue', item); } return item; } finally { this.releaseLock(); } } peek() { return this.queue[0]; } size() { return this.queue.length; } isEmpty() { return this.queue.length === 0; } async clear() { await this.acquireLock(); try { this.queue = []; this.emit('clear'); } finally { this.releaseLock(); } } } exports.ThreadSafeQueue = ThreadSafeQueue; class StateManager { constructor() { this.maps = new Map(); this.sets = new Map(); this.counters = new Map(); this.queues = new Map(); } static getInstance() { if (!StateManager.instance) { StateManager.instance = new StateManager(); } return StateManager.instance; } getMap(name) { if (!this.maps.has(name)) { this.maps.set(name, new ThreadSafeMap()); } return this.maps.get(name); } getSet(name) { if (!this.sets.has(name)) { this.sets.set(name, new ThreadSafeSet()); } return this.sets.get(name); } getCounter(name) { if (!this.counters.has(name)) { this.counters.set(name, new ThreadSafeCounter()); } return this.counters.get(name); } getQueue(name) { if (!this.queues.has(name)) { this.queues.set(name, new ThreadSafeQueue()); } return this.queues.get(name); } removeState(name) { const removed = this.maps.delete(name) || this.sets.delete(name) || this.counters.delete(name) || this.queues.delete(name); return removed; } getStats() { return { maps: this.maps.size, sets: this.sets.size, counters: this.counters.size, queues: this.queues.size, total: this.maps.size + this.sets.size + this.counters.size + this.queues.size }; } async clearAll() { const promises = []; for (const map of this.maps.values()) { promises.push(map.safeClear()); } for (const set of this.sets.values()) { promises.push(set.safeClear()); } for (const queue of this.queues.values()) { promises.push(queue.clear()); } await Promise.all(promises); this.maps.clear(); this.sets.clear(); this.counters.clear(); this.queues.clear(); } } exports.StateManager = StateManager; exports.stateManager = StateManager.getInstance(); //# sourceMappingURL=threadSafeState.js.map