|
|
import {promisify} from 'node:util';import { validateIpcMethod, handleEpipeError, handleSerializationError, disconnect,} from './validation.js';import {startSendMessage, endSendMessage} from './outgoing.js';import {handleSendStrict, waitForStrictResponse} from './strict.js';
// Like `[sub]process.send()` but promise-based.
// We do not `await subprocess` during `.sendMessage()` nor `.getOneMessage()` since those methods are transient.
// Users would still need to `await subprocess` after the method is done.
// Also, this would prevent `unhandledRejection` event from being emitted, making it silent.
export const sendMessage = ({anyProcess, channel, isSubprocess, ipc}, message, {strict = false} = {}) => { const methodName = 'sendMessage'; validateIpcMethod({ methodName, isSubprocess, ipc, isConnected: anyProcess.connected, });
return sendMessageAsync({ anyProcess, channel, methodName, isSubprocess, message, strict, });};
const sendMessageAsync = async ({anyProcess, channel, methodName, isSubprocess, message, strict}) => { const wrappedMessage = handleSendStrict({ anyProcess, channel, isSubprocess, message, strict, }); const outgoingMessagesState = startSendMessage(anyProcess, wrappedMessage, strict); try { await sendOneMessage({ anyProcess, methodName, isSubprocess, wrappedMessage, message, }); } catch (error) { disconnect(anyProcess); throw error; } finally { endSendMessage(outgoingMessagesState); }};
// Used internally by `cancelSignal`
export const sendOneMessage = async ({anyProcess, methodName, isSubprocess, wrappedMessage, message}) => { const sendMethod = getSendMethod(anyProcess);
try { await Promise.all([ waitForStrictResponse(wrappedMessage, anyProcess, isSubprocess), sendMethod(wrappedMessage), ]); } catch (error) { handleEpipeError({error, methodName, isSubprocess}); handleSerializationError({ error, methodName, isSubprocess, message, }); throw error; }};
// [sub]process.send() promisified, memoized
const getSendMethod = anyProcess => { if (PROCESS_SEND_METHODS.has(anyProcess)) { return PROCESS_SEND_METHODS.get(anyProcess); }
const sendMethod = promisify(anyProcess.send.bind(anyProcess)); PROCESS_SEND_METHODS.set(anyProcess, sendMethod); return sendMethod;};
const PROCESS_SEND_METHODS = new WeakMap();
|