| 150 | // the WorkspaceShell exec bracket settles right away. Used by the |
| 151 | // multi-backend selection tests. |
| 152 | function execBackend(id: string, onExec: (command: string) => void): WorkspaceBackend { |
| 153 | const shell: import("@cloudflare/computer-rpc").ShellRPC = { |
| 154 | async exec(input) { |
| 155 | onExec(input.command); |
| 156 | const execId = input.id ?? `${id}-${Math.random().toString(36).slice(2)}`; |
| 157 | return { |
| 158 | id: execId, |
| 159 | events: new ReadableStream<import("@cloudflare/computer-rpc").ExecEvent>({ |
| 160 | start(c) { |
| 161 | c.enqueue({ id: execId, seq: 1, name: "exit", value: 0 }); |
| 162 | c.close(); |
| 163 | }, |
| 164 | }), |
| 165 | }; |
| 166 | }, |
| 167 | getExec: () => Promise.reject(new Error("not used")), |
| 168 | killExec: () => Promise.reject(new Error("not used")), |
| 169 | disposeExec: () => Promise.reject(new Error("not used")), |
| 170 | }; |
| 171 | return { |
| 172 | id, |
| 173 | type: "fake", |
| 174 | async connect(): Promise<BackendHandle> { |
| 175 | return { |
| 176 | rpc: { sync: fakeRpc(), shell }, |
| 177 | sync: "none", |
| 178 | close: async () => {}, |
| 179 | }; |
| 180 | }, |
| 181 | }; |
| 182 | } |
| 183 | |
| 184 | // Drain an ExecHandle (or its result()-aware wrapper) to settle |
| 185 | // the WorkspaceShell push/pull bracket. The selection tests don't |