(server: RuntimeServer, adapter: RuntimeNodeProcessAdapter)
| 108 | } |
| 109 | |
| 110 | export function registerRuntimeNodeProcessModule(server: RuntimeServer, adapter: RuntimeNodeProcessAdapter): () => void { |
| 111 | server.registerNotification("process/started") |
| 112 | server.registerNotification("process/output") |
| 113 | server.registerNotification("process/exit") |
| 114 | server.registerNotification("process/error") |
| 115 | |
| 116 | const removeLifecycleListener = adapter.addLifecycleListener((event) => { |
| 117 | if (event.type === "started") { |
| 118 | const runtime = server.supervisor.create({ |
| 119 | runtimeId: processRuntimeId(event.processId), |
| 120 | kind: "process", |
| 121 | status: "running", |
| 122 | scope: { |
| 123 | ownerType: "process", |
| 124 | ownerId: event.processId, |
| 125 | rootPath: event.cwd, |
| 126 | }, |
| 127 | nativeId: event.processId, |
| 128 | pid: event.pid, |
| 129 | pgid: event.pgid, |
| 130 | processLabel: event.label, |
| 131 | processStartedAt: event.processStartedAt ?? now(), |
| 132 | }) |
| 133 | server.notify("runtime/created", runtime) |
| 134 | server.notify("process/started", { ...event, runtimeId: runtime.runtimeId }) |
| 135 | return |
| 136 | } |
| 137 | |
| 138 | if (event.type === "output") { |
| 139 | server.supervisor.touchByOwner("process", event.processId) |
| 140 | server.notify("process/output", event) |
| 141 | return |
| 142 | } |
| 143 | |
| 144 | if (event.type === "exit") { |
| 145 | const status = event.signal ? "stopped" : event.exitCode === 0 ? "completed" : "failed" |
| 146 | const runtimeId = processRuntimeId(event.processId) |
| 147 | const current = server.supervisor.get(runtimeId) |
| 148 | if (!isTerminalStatus(current?.status)) { |
| 149 | const runtime = server.supervisor.update(runtimeId, { |
| 150 | status, |
| 151 | exitedAt: now(), |
| 152 | exitCode: event.exitCode, |
| 153 | signal: event.signal, |
| 154 | }) |
| 155 | server.notify(status === "completed" ? "runtime/completed" : status === "stopped" ? "runtime/stopped" : "runtime/failed", runtime) |
| 156 | } |
| 157 | server.notify("process/exit", event) |
| 158 | return |
| 159 | } |
| 160 | |
| 161 | const runtimeId = processRuntimeId(event.processId) |
| 162 | const current = server.supervisor.get(runtimeId) |
| 163 | if (!isTerminalStatus(current?.status)) { |
| 164 | const runtime = server.supervisor.update(runtimeId, { |
| 165 | status: "failed", |
| 166 | error: event.error, |
| 167 | }) |
no test coverage detected