| 81 | } |
| 82 | |
| 83 | function fakeRpc(options: FakeRpcOptions = {}): FakeRpc { |
| 84 | const events = options.events ?? [{ id: "_", seq: 1, name: "exit", value: 0 }]; |
| 85 | const mintedId = options.mintedId ?? "runner-minted-id"; |
| 86 | const calls: FakeRpc["calls"] = { |
| 87 | exec: [], |
| 88 | getExec: [], |
| 89 | killExec: [], |
| 90 | }; |
| 91 | |
| 92 | function makeStream(id: string): ReadableStream<ExecEvent> { |
| 93 | return new ReadableStream<ExecEvent>({ |
| 94 | start(c) { |
| 95 | for (const e of events) c.enqueue({ ...e, id }); |
| 96 | if (options.streamError !== undefined) { |
| 97 | c.error(options.streamError); |
| 98 | return; |
| 99 | } |
| 100 | c.close(); |
| 101 | }, |
| 102 | }); |
| 103 | } |
| 104 | |
| 105 | const sync: SyncRPC = { |
| 106 | async push() { |
| 107 | throw new Error("not wired"); |
| 108 | }, |
| 109 | async fetchChanges() { |
| 110 | throw new Error("not wired"); |
| 111 | }, |
| 112 | async readEntry() { |
| 113 | return null; |
| 114 | }, |
| 115 | async watermarks() { |
| 116 | return { currentRev: 0, pushRev: 0, fetchCursor: { rev: 0, path: null } }; |
| 117 | }, |
| 118 | async hasObjects() { |
| 119 | return []; |
| 120 | }, |
| 121 | fetchObjects() { |
| 122 | throw new Error("not wired"); |
| 123 | }, |
| 124 | async pushObjects() { |
| 125 | throw new Error("not wired"); |
| 126 | }, |
| 127 | }; |
| 128 | |
| 129 | const shell: ShellRPC = { |
| 130 | async exec(input) { |
| 131 | calls.exec.push({ |
| 132 | command: input.command, |
| 133 | id: input.id, |
| 134 | cwd: input.cwd, |
| 135 | timeoutMs: input.timeoutMs, |
| 136 | }); |
| 137 | if (options.throwOnExec !== undefined) throw options.throwOnExec; |
| 138 | const id = input.id ?? mintedId; |
| 139 | return { id, events: makeStream(id) }; |
| 140 | }, |