diff --git a/packages/runtime-node/src/index.ts b/packages/runtime-node/src/index.ts index 15fd2e46b..70c2c5233 100644 --- a/packages/runtime-node/src/index.ts +++ b/packages/runtime-node/src/index.ts @@ -1,4 +1,3 @@ -export * from './ipc-host.js'; export * from './parent-port-host.js'; export * from './ws-node-host.js'; export * from './launch-http-server.js'; diff --git a/packages/runtime-node/src/ipc-host.ts b/packages/runtime-node/src/ipc-host.ts deleted file mode 100644 index d9fbf0f05..000000000 --- a/packages/runtime-node/src/ipc-host.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { BaseHost, type Message } from '@dazl/engine-core'; -import type { ChildProcess } from 'node:child_process'; -import { SafeDisposable, type IDisposable } from '@dazl/patterns'; - -const isParentProcess = (process: NodeJS.Process | ChildProcess): process is NodeJS.Process => { - return (process as NodeJS.Process).constructor.name === 'process'; -}; - -export class IPCHost extends BaseHost implements IDisposable { - private disposables = new SafeDisposable(IPCHost.name); - dispose = this.disposables.dispose; - isDisposed = this.disposables.isDisposed; - private envs = new Set(); - - constructor(private process: NodeJS.Process | ChildProcess) { - super(); - process.on('message', this.onMessage); - process.once('disconnect', () => { - process.off('message', this.onMessage); - for (const env of this.envs) { - this.emitMessageHandlers({ - from: env, - type: 'dispose', - to: '*', - origin: env, - forwardingChain: [], - }); - } - }); - this.disposables.add('process listeners', () => this.process.removeAllListeners()); - this.disposables.add('clear handlers', () => this.handlers.clear()); - } - - private onMessage: (...args: any[]) => void = (message) => { - this.emitMessageHandlers(message); - }; - - public postMessage(data: Message) { - this.envs.add(data.to); - if (!this.process.send) { - throw new Error('this process is not forked. There is not to send message to'); - } - const disposeHandlers = (e: Error | null) => { - if (e) { - this.emitMessageHandlers({ - from: data.to, - type: 'dispose', - to: '*', - origin: data.to, - forwardingChain: [], - }); - } - }; - - if (isParentProcess(this.process)) { - this.process.send(data, undefined, undefined, disposeHandlers); - } else { - this.process.send(data, disposeHandlers); - } - } -} diff --git a/packages/runtime-node/test/node-com.unit.ts b/packages/runtime-node/test/node-com.unit.ts index e2156aad3..2633ee11e 100644 --- a/packages/runtime-node/test/node-com.unit.ts +++ b/packages/runtime-node/test/node-com.unit.ts @@ -1,5 +1,5 @@ +import { createDisposables } from '@dazl/create-disposables'; import { - BaseHost, Communication, Environment, WsClientHost, @@ -7,12 +7,10 @@ import { type DisposeMessage, type Message, } from '@dazl/engine-core'; -import { IPCHost, WsServerHost } from '@dazl/engine-runtime-node'; -import { createDisposables } from '@dazl/create-disposables'; +import { WsServerHost } from '@dazl/engine-runtime-node'; import { createWaitForCall } from '@dazl/wait-for-call'; import { expect } from 'chai'; import { safeListeningHttpServer } from 'create-listening-server'; -import { fork } from 'node:child_process'; import type { Socket } from 'node:net'; import { waitFor } from 'promise-assist'; import sinon, { spy } from 'sinon'; @@ -321,50 +319,3 @@ describe('Socket communication', () => { expect(secondClient.isConnected(), 'second connected').to.eql(true); }); }); - -describe('IPC communication', () => { - const disposables = createDisposables(); - afterEach(() => disposables.dispose()); - - it('communication with forked process', async () => { - const mainHost = new BaseHost(); - const communication = new Communication(mainHost, 'main'); - const forked = fork(new URL('./process-entry.js', import.meta.url)); - disposables.add(() => forked.kill()); - const host = new IPCHost(forked); - communication.registerEnv('process', host); - communication.registerMessageHandler(host); - const proxy = communication.apiProxy<{ echo(): string }>( - { - id: 'process', - }, - { id: 'myApi' }, - ); - - expect(await proxy.echo()).to.eq('yo'); - }); - - it('handles forked process closing', async () => { - const mainHost = new BaseHost(); - const communication = new Communication(mainHost, 'main'); - const forked = fork(new URL('./process-entry.js', import.meta.url)); - const host = new IPCHost(forked); - communication.registerEnv('process', host); - communication.registerMessageHandler(host); - const proxy = communication.apiProxy<{ echo(): string }>( - { - id: 'process', - }, - { id: 'myApi' }, - ); - - forked.kill(); - const { waitForCall, spy } = createWaitForCall<(e: Error) => void>(); - proxy.echo().catch(spy); - await waitForCall((args) => { - expect(args[0].message).to.have.string( - 'Remote call failed in "process" - environment disconnected at "main"', - ); - }); - }); -}); diff --git a/packages/runtime-node/test/process-entry.ts b/packages/runtime-node/test/process-entry.ts deleted file mode 100644 index 48b581fa1..000000000 --- a/packages/runtime-node/test/process-entry.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Communication } from '@dazl/engine-core'; -import { IPCHost } from '@dazl/engine-runtime-node'; - -const ipcHost = new IPCHost(process); -const com = new Communication(ipcHost, 'process'); -com.registerAPI( - { id: 'myApi' }, - { - echo: () => 'yo', - }, -);