> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/BintzGavin/helios/llms.txt
> Use this file to discover all available pages before exploring further.

# Render session

> Frame iteration and rendering control for Helios

## RenderSessionOptions

Configuration options for a render session.

```typescript theme={null}
interface RenderSessionOptions {
  startFrame: number;
  endFrame: number;
  abortSignal?: AbortSignal;
}
```

<ResponseField name="startFrame" type="number" required>
  First frame to render (must be non-negative)
</ResponseField>

<ResponseField name="endFrame" type="number" required>
  Last frame to render (must be >= startFrame)
</ResponseField>

<ResponseField name="abortSignal" type="AbortSignal">
  Optional AbortSignal to cancel the render session
</ResponseField>

## RenderSession

Async iterable session for rendering frames sequentially.

```typescript theme={null}
class RenderSession implements AsyncIterable<number> {
  constructor(helios: Helios, options: RenderSessionOptions)
  
  async *[Symbol.asyncIterator](): AsyncIterator<number>
}
```

<ParamField path="helios" type="Helios" required>
  Helios instance to control
</ParamField>

<ParamField path="options" type="RenderSessionOptions" required>
  Render session configuration
</ParamField>

### Usage

RenderSession is an async iterable that yields frame numbers. For each frame, it:

1. Seeks the Helios instance to the frame
2. Waits for the frame to be stable (all animations settled)
3. Yields the frame number
4. Checks if the session was aborted

### Example

```typescript theme={null}
import { Helios } from '@helios-project/core';
import { RenderSession } from '@helios-project/core';

const helios = new Helios({ duration: 5, fps: 30 });

// Render all frames
const session = new RenderSession(helios, {
  startFrame: 0,
  endFrame: 150
});

for await (const frame of session) {
  console.log(`Rendering frame ${frame}`);
  // Capture frame, encode, etc.
  const canvas = document.querySelector('canvas');
  const blob = await canvas.toBlob();
  // ... save blob
}
```

### Partial rendering

```typescript theme={null}
// Render a specific range
const partialSession = new RenderSession(helios, {
  startFrame: 30,
  endFrame: 90
});

for await (const frame of partialSession) {
  // Only renders frames 30-90
}
```

### Aborting a session

```typescript theme={null}
const controller = new AbortController();

const session = new RenderSession(helios, {
  startFrame: 0,
  endFrame: 1000,
  abortSignal: controller.signal
});

// Cancel after 5 seconds
setTimeout(() => controller.abort(), 5000);

try {
  for await (const frame of session) {
    console.log(`Rendering frame ${frame}`);
  }
} catch (error) {
  console.log('Render aborted');
}
```

### Integration with capture

```typescript theme={null}
import { RenderSession } from '@helios-project/core';
import { captureFrame } from '@helios-project/renderer';

const helios = new Helios({ duration: 10, fps: 30 });
const frames: Blob[] = [];

const session = new RenderSession(helios, {
  startFrame: 0,
  endFrame: 300
});

for await (const frame of session) {
  const blob = await captureFrame();
  frames.push(blob);
  
  // Progress reporting
  const progress = ((frame / 300) * 100).toFixed(1);
  console.log(`Progress: ${progress}%`);
}

console.log('Render complete!');
```

### Error handling

Throws an error if:

* `startFrame` is negative
* `endFrame` is less than `startFrame`

```typescript theme={null}
// Invalid: negative startFrame
try {
  new RenderSession(helios, {
    startFrame: -10,
    endFrame: 100
  });
} catch (error) {
  console.error(error.message);
  // 'Invalid startFrame: -10. Must be non-negative.'
}

// Invalid: endFrame < startFrame
try {
  new RenderSession(helios, {
    startFrame: 100,
    endFrame: 50
  });
} catch (error) {
  console.error(error.message);
  // 'Invalid range: startFrame (100) > endFrame (50).'
}
```

### Notes

* The session automatically waits for each frame to be stable before yielding
* Abort checks occur before starting, before each frame, and after waiting
* The session gracefully exits when aborted (does not throw)
* Frame seeking is sequential; parallel rendering requires multiple instances
