info stream

GitOrigin-RevId: 5d4cb01c250768ca00e15368b9c616b467e4f9ba
This commit is contained in:
Domagoj Kriskovic
2026-04-20 13:49:32 +02:00
committed by Copybot
parent 6ccbefc3f8
commit 09af91a936
6 changed files with 46 additions and 17 deletions

View File

@@ -5,7 +5,7 @@ import type {
} from './pyodide-worker-messages'
export type OutputCallback = (
stream: 'stdout' | 'stderr',
stream: 'stdout' | 'stderr' | 'info',
line: string,
fileId: string,
executionId: string

View File

@@ -28,7 +28,7 @@ export type LoadingFailedEvent = { type: 'loading-failed'; error: string }
export type OutputLineEvent = {
type: 'output-line'
stream: 'stdout' | 'stderr'
stream: 'stdout' | 'stderr' | 'info'
line: string
fileId: string
executionId: string

View File

@@ -74,9 +74,12 @@ export default function PythonOutputPane() {
{error && (
<div className="ide-redesign-python-output-pane-error">{error}</div>
)}
{output.map((line, index) => (
<div className="ide-redesign-python-output-pane-line" key={index}>
{line}
{output.map((entry, index) => (
<div
className={`ide-redesign-python-output-pane-line ide-redesign-python-output-pane-line-${entry.stream}`}
key={index}
>
{entry.line}
</div>
))}
</div>

View File

@@ -21,8 +21,13 @@ export type ExecutionContext = {
type Listener = () => void
export type OutputLine = {
stream: 'stdout' | 'stderr' | 'info'
line: string
}
export type PythonRunnerState = {
output: string[]
output: OutputLine[]
status: ExecutionStatus
error: string | null
}
@@ -116,11 +121,13 @@ export class PythonRunner {
this.updateState({ status: 'finished' })
}
},
onOutput: (_stream, line, fileId, executionId) => {
onOutput: (stream, line, fileId, executionId) => {
if (fileId !== this.fileId || this.activeExecutionId !== executionId) {
return
}
this.updateState({ output: appendCapped(this.state.output, line) })
this.updateState({
output: appendCapped(this.state.output, { stream, line }),
})
},
})
}
@@ -185,7 +192,10 @@ export class PythonRunner {
status: 'loading',
output:
this.state.status === 'running'
? appendCapped(this.state.output, 'Execution interrupted')
? appendCapped(this.state.output, {
stream: 'info',
line: 'Execution interrupted',
})
: this.state.output,
})
}
@@ -198,8 +208,11 @@ export class PythonRunner {
}
}
function appendCapped(existing: string[], line: string): string[] {
const updated = [...existing, line]
function appendCapped(
existing: OutputLine[],
entry: OutputLine
): OutputLine[] {
const updated = [...existing, entry]
return updated.length > MAX_OUTPUT_LINES
? updated.slice(-MAX_OUTPUT_LINES)
: updated

View File

@@ -92,6 +92,14 @@
word-break: break-word;
}
.ide-redesign-python-output-pane-line-info {
color: var(--content-secondary);
}
.ide-redesign-python-output-pane-line-stderr {
color: var(--red-50);
}
.ide-redesign-python-output-pane-placeholder,
.ide-redesign-python-output-pane-error {
white-space: pre-wrap;

View File

@@ -135,7 +135,9 @@ describe('PythonRunner', function () {
executionId: runMsg.executionId,
outputs: [],
})
expect(runner.getState().output).to.deep.equal(['first run output'])
expect(runner.getState().output).to.deep.equal([
{ stream: 'stdout', line: 'first run output' },
])
await runner.run()
expect(runner.getState().output).to.deep.equal([])
@@ -193,7 +195,10 @@ describe('PythonRunner', function () {
executionId: runMsg.executionId,
})
expect(runner.getState().output).to.deep.equal(['line 1', 'line 2'])
expect(runner.getState().output).to.deep.equal([
{ stream: 'stdout', line: 'line 1' },
{ stream: 'stderr', line: 'line 2' },
])
})
it('ignores output for a different fileId', async function () {
@@ -250,8 +255,8 @@ describe('PythonRunner', function () {
const output = runner.getState().output
expect(output).to.have.length(100)
expect(output[0]).to.equal('line 10')
expect(output[99]).to.equal('line 109')
expect(output[0]).to.deep.equal({ stream: 'stdout', line: 'line 10' })
expect(output[99]).to.deep.equal({ stream: 'stdout', line: 'line 109' })
})
})
@@ -274,8 +279,8 @@ describe('PythonRunner', function () {
expect(runner.getState().status).to.equal('loading')
expect(runner.getState().output).to.deep.equal([
'partial output',
'Execution interrupted',
{ stream: 'stdout', line: 'partial output' },
{ stream: 'info', line: 'Execution interrupted' },
])
})