import { MessageTypes, Serializable, StoredPromise } from '../types'; import { BaseMessage, DataType } from '../other/message'; import { ClusterManager } from '../core/clusterManager'; import { ClusterClient } from '../core/clusterClient'; /** Handles promises by storing them in a map and resolving them when the response is received. */ export class PromiseHandler { /** List of promises and their unique identifiers. */ nonces: Map = new Map(); /** Creates an instance of PromiseHandler. */ constructor(private instance: ClusterManager | ClusterClient) {} /** Resolves the promise with the data received. */ public resolve(message: BaseMessage): void { const promise = this.nonces.get(message._nonce); if (!promise) return this.instance._debug(`Received a message with an unknown nonce: ${message._nonce}`); if (promise.timeout) clearTimeout(promise.timeout); this.nonces.delete(message._nonce); const errorTypes = [ MessageTypes.ClientEvalResponseError, MessageTypes.ClientManagerEvalResponseError, MessageTypes.ClientBroadcastResponseError, ]; if (!errorTypes.includes(message._type)) { promise.resolve(message.data); return; } const data = message.data as Partial['data']>; const error = new Error([data.message, data.stack].filter(Boolean).join('\n') || 'Unknown IPC error'); if (data.script) error.cause = data.script; if (data.stack) error.stack = data.stack; if (data.name) error.name = data.name; promise.reject(error); console.error('An error occurred while resolving an IPC promise:', data); } /** Creates a promise and stores it in the map. */ public async create(nonce: string, timeout?: number): Promise { return await new Promise((resolve, reject) => { if (timeout === undefined || timeout < 0) this.nonces.set(nonce, { resolve, reject }); else this.nonces.set(nonce, { resolve, reject, timeout: setTimeout(() => { this.nonces.delete(nonce); reject(new Error('Promise timed out.')); }, timeout) as NodeJS.Timeout, }); }); } }