Skip to main content

Overview

NativeSpanFeed is a zero-copy wrapper over native Zig memory for efficient streaming of terminal output. It manages chunks of data in native memory and provides spans (slices) to TypeScript without copying.
This is not a full stream interface - it’s optimized for zero-copy access to native memory buffers.

Creating a Stream

function
Create a new native span feed stream
NativeSpanFeedOptions
Stream configuration options
function
Attach to an existing native stream by pointer
bigint | number
required
Native pointer to existing stream

Options

object
Configuration for span feed behavior
number
Initial size for memory chunks
number
Maximum size for memory chunks
GrowthPolicy
How chunks grow when more space is needed

Event Handlers

function
Register a handler for data availability
(data: Uint8Array) => void | Promise<void>
required
Callback invoked when data is available. Receives a zero-copy view into native memory.
Returns: Cleanup function to unregister the handler
The Uint8Array provided to your handler is a view into native memory. Do not retain references to it after the handler returns. If you need the data later, copy it.
function
Register an error handler
(code: number) => void
required
Callback invoked on error with error code
Returns: Cleanup function to unregister the handler

Stream Control

function
Manually drain all available data
Calls registered data handlers for all pending spans. Usually not needed as data is drained automatically when handlers are registered.
function
Close the stream and free resources
After calling close(), the stream cannot be reused. Do not call any methods on a closed stream.

Properties

Pointer
Native pointer to the underlying stream

Types

DataHandler

Data handlers can be synchronous or asynchronous. Async handlers keep the underlying memory chunk pinned until the promise resolves.

GrowthPolicy

Controls how memory chunks grow:
  • "linear" - Add fixed amount each time
  • "exponential" - Double size each time
  • "fibonacci" - Use Fibonacci sequence

NativeSpanFeedStats

Example: Basic Usage

Example: Async Handler

Example: Copy Data for Later Use

Memory Management

The native span feed uses a sophisticated memory management system:
  1. Chunks: Data is allocated in chunks in native memory
  2. Spans: Each data callback receives a span (slice) of a chunk
  3. Reference Counting: Chunks are reference counted and freed when no longer needed
  4. Zero-Copy: Data is never copied from native memory to JavaScript unless you explicitly copy it

Lifecycle

  1. Data is written to a chunk in native memory
  2. When data is available, the stream emits a “data available” event
  3. Your handler receives a Uint8Array view into the chunk
  4. After your handler returns (or async handler resolves), the reference count is decremented
  5. When a chunk’s reference count reaches zero, it’s freed
Critical: The Uint8Array passed to your handler is only valid during the handler execution. Do not store references to it. If you need the data later, copy it to a new array.

Performance Tips

  • Use synchronous handlers when possible (async handlers keep chunks pinned longer)
  • Process data immediately in the handler rather than queuing it
  • If you must store data, copy only what you need
  • Consider using drainAll() if you want to batch process multiple spans
  • Unregister handlers when no longer needed to avoid memory leaks