MCPcopy Create free account
hub / github.com/cloudflare/computer / pipeEvents

Function pipeEvents

packages/computer/src/shell.ts:291–370  ·  view source on GitHub ↗
(
  source: ReadableStream<ExecEvent>,
  encoding: E | undefined,
)

Source from the content-addressed store, hash-verified

289}
290
291function pipeEvents<E extends ExecEncoding>(
292 source: ReadableStream<ExecEvent>,
293 encoding: E | undefined,
294): ReadableStream<WorkspaceExecEvent<E>> {
295 if (encoding !== "utf8") {
296 // Identity pipe — the wire shape already matches.
297 return source as unknown as ReadableStream<WorkspaceExecEvent<E>>;
298 }
299 // Per-stream TextDecoders preserve multi-byte boundaries
300 // across chunk splits.
301 const stdoutDec = new TextDecoder("utf-8", { fatal: false });
302 const stderrDec = new TextDecoder("utf-8", { fatal: false });
303 let stdoutMeta: { id: string; seq: number } | undefined;
304 let stderrMeta: { id: string; seq: number } | undefined;
305 let lastSeq = 0;
306 const enqueue = (
307 controller: TransformStreamDefaultController<WorkspaceExecEvent<E>>,
308 event: WorkspaceExecEvent<E>,
309 ) => {
310 lastSeq = event.seq;
311 controller.enqueue(event);
312 };
313 const flushPending = (
314 controller: TransformStreamDefaultController<WorkspaceExecEvent<E>>,
315 beforeSeq?: number,
316 ) => {
317 const pending: Array<{
318 id: string;
319 seq: number;
320 name: "stdout" | "stderr";
321 value: Chunk<E>;
322 }> = [];
323 const stdout = stdoutDec.decode();
324 const stderr = stderrDec.decode();
325 if (stdout && stdoutMeta) {
326 pending.push({ ...stdoutMeta, name: "stdout", value: stdout as Chunk<E> });
327 }
328 if (stderr && stderrMeta) {
329 pending.push({ ...stderrMeta, name: "stderr", value: stderr as Chunk<E> });
330 }
331 pending.sort((a, b) => a.seq - b.seq);
332 const span = beforeSeq !== undefined && beforeSeq > lastSeq ? beforeSeq - lastSeq : 1;
333 for (let index = 0; index < pending.length; index++) {
334 const event = pending[index];
335 enqueue(controller, {
336 ...event,
337 seq: lastSeq + (span * (index + 1)) / (pending.length + 1),
338 });
339 }
340 stdoutMeta = undefined;
341 stderrMeta = undefined;
342 };
343 return source.pipeThrough(
344 new TransformStream<ExecEvent, WorkspaceExecEvent<E>>({
345 transform(event, controller) {
346 if (event.name === "stdout") {
347 stdoutMeta = { id: event.id, seq: event.seq };
348 enqueue(controller, {

Callers 1

wrapHandleFunction · 0.85

Calls 1

pipeThroughMethod · 0.65

Tested by

no test coverage detected