| 148 | } |
| 149 | |
| 150 | append(runId: string, chunk: StreamChunk): Promise<number> { |
| 151 | const state = this.runs.get(runId) |
| 152 | if (!state) { |
| 153 | return Promise.reject(new Error(`run-log: unknown runId "${runId}"`)) |
| 154 | } |
| 155 | if (isTerminalRunStatus(state.record.status)) { |
| 156 | return Promise.reject( |
| 157 | new Error( |
| 158 | `run-log: cannot append to terminal run "${runId}" (status=${state.record.status})`, |
| 159 | ), |
| 160 | ) |
| 161 | } |
| 162 | // Derive seq from the record's cursor (not `chunks.length`) so the gap-free |
| 163 | // invariant holds the same way the durable backend computes it, even if the |
| 164 | // backlog is ever trimmed/compacted. |
| 165 | const seq = state.record.lastSeq + 1 |
| 166 | state.chunks.push(chunk) |
| 167 | state.record.lastSeq = seq |
| 168 | state.record.updatedAt = this.now() |
| 169 | this.wake(state) |
| 170 | return Promise.resolve(seq) |
| 171 | } |
| 172 | |
| 173 | finish( |
| 174 | runId: string, |